我如何实现有效的撤消/重做到我的WinForms应用程序

本文关键字:重做 撤消 我的 应用程序 WinForms 有效 何实现 实现 | 更新日期: 2023-09-27 18:08:22

我有一个WinForm文本编辑器

我希望能够允许用户在富文本框中撤消和重做更改,就像他们可以在Microsoft Word中一样。

我花了一周左右的时间研究如何做到这一点,大多数结果似乎都与图形应用程序有关。

标准richTextBox1.Undo();给出令人失望的结果,因为它撤消了用户编写的所有内容。

有谁知道我怎样才能实现有效的撤销/重做吗?最好是一个字一个字地取消/重新执行操作,而不是一个字一个字地取消/重新执行操作。

我如何实现有效的撤消/重做到我的WinForms应用程序

这是一个非常基本的想法,我相信还可以做很多改进。

我将创建一个String Array,并在数组中增量存储RichTextBox的值(在TextChanged事件中,根据您自己的条件)。当您存储该值时,增加计数器的值,例如stackcount。当用户撤消时,减少stackcount并设置RichTextBox.Text = array(stackcount)。如果它们重做,则增加计数器的值并再次设置该值。如果他们撤消然后更改文本,然后清除所有的值。

我相信很多其他人可能对此有更好的建议/更改,所以请在评论中发表,我会更新,或者自己编辑!

c#示例

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RedoUndoApp
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    public string[] RTBRedoUndo;
    public int StackCount = 0;
    public int OldLength = 0;
    public int ChangeToSave = 5;
    public bool IsRedoUndo = false;
    private void Form1_Load(object sender, EventArgs e)
    {
        RTBRedoUndo = new string[10000];
        RTBRedoUndo[0] = "";
    }
    private void undo_Click(object sender, EventArgs e)
    {
        IsRedoUndo = true;
        if (StackCount > 0 && RTBRedoUndo[StackCount - 1] != null)
        {
            StackCount = StackCount - 1;
            richTextBox1.Text = RTBRedoUndo[StackCount];
        }
    }
    private void redo_Click(object sender, EventArgs e)
    {
        IsRedoUndo = true;
        if (StackCount > 0 && RTBRedoUndo[StackCount + 1] != null)
        {
            StackCount = StackCount + 1;
            richTextBox1.Text = RTBRedoUndo[StackCount];
        }
    }
    private void richTextBox1_TextChanged(object sender, EventArgs e)
    {
        if (IsRedoUndo == false && richTextBox1.Text.Substring(richTextBox1.Text.Length - 1, 1) == " ")//(Math.Abs(richTextBox1.Text.Length - OldLength) >= ChangeToSave && IsRedoUndo == false)
        {
            StackCount = StackCount + 1;
            RTBRedoUndo[StackCount] = richTextBox1.Text;
            OldLength = richTextBox1.Text.Length;
        }
    }
    private void undo_MouseUp(object sender, MouseEventArgs e)
    {
        IsRedoUndo = false;
    }
    private void redo_MouseUp(object sender, MouseEventArgs e)
    {
        IsRedoUndo = false;
    }
}
}

方法之一是使用TextChanged事件定期存储richtextbox的内容。数组或列表中的文本,如堆栈。当你撤销时,"弹出堆栈"并将堆栈上的最新版本复制到richtextbox.text.

TextChange可以决定是否将更改保存到堆栈中,无论是新单词,新行还是新字符。