c# - 如何在我的 WinForms 应用程序中实现有效的撤消/重做?

标签 c# winforms visual-studio richtextbox undo-redo

我有一个 WinForm 文本编辑器。

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

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

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

有没有人知道我可以如何实现有效的撤消/重做?最好是逐字撤消/重做操作,而不是逐字符撤消/重做。

最佳答案

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

我会创建一个 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;
    }
}
}

关于c# - 如何在我的 WinForms 应用程序中实现有效的撤消/重做?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15891487/

相关文章:

c# - 如何重写 Regex.Replace(由于异步 api)

c# - 如何检测进程是否移动了鼠标光标而不是用户?

git - 与 Visual Studio 中的 merge 混淆

c# - 将 FtpWebRequest 与 SSL 结合使用时出现超时错误

c# - 如何将 xaml 属性绑定(bind)到另一个类中的静态变量?

c# - 如何在 C# 中获取 HTMLAgilityPack DOM 元素的边界框?

c# - Thread.CurrentPrincipal Identity.Name 在 asp.net mvc 6 (vNext) 中为空

C# - 将数据表绑定(bind)到reportviewer

c# - 如何隐藏和取消隐藏 XtraTabControl 的页面?

c# - 我可以在 Visual Studio 2010 中折叠 foreach、using 和其他 c# 代码块吗?