【问题标题】:How to Undo and Redo in C# (Rich Text Box)如何在 C# 中撤消和重做(富文本框)
【发布时间】:2013-03-24 05:57:58
【问题描述】:

我已经尝试让 undoredo 在我的文本编辑器中工作大约 3 天了。它让我头疼。

我有一个文本框(名为richTextBoxPrintCtrl1),我希望能够撤消和*重做*(逐字)。

所以如果我点击撤消按钮,它撤消最后一个字。如果我随后单击重做按钮,它重做最后一个字。

有人可以帮我解决这个问题吗?

richTextBoxPrintCtrl1.Undo(); 不能很好地工作。它会删除在文本框中输入的所有内容。

提前感谢您的帮助。

我知道这个问题以前被问过很多次,但我无法使用我在 SO 上浏览的问题中的信息来解决这个问题。

【问题讨论】:

  • 我是编程新手,如果我是愚蠢的,请原谅我。
  • 之前有几个关于这个主题的问题。你应该在 StackOverflow 上搜索它。这个,比如stackoverflow.com/questions/8025926/…
  • 正如我所说,我已经搜索了各种来源(包括 SO),但找不到我可以理解/实施的来源。
  • 那么,如果您发布的代码显示了您迄今为止所做的事情,将会有所帮助。正如其他答案所说,您必须在每次触发 TextChanged 事件时使用堆栈实现自己的自定义撤消,然后在每次调用撤消时弹出堆栈。
  • 问题是我无法让任何类型的撤消工作(除了richTextBoxPrintCtrl1.Undo();)。

标签: c# winforms visual-studio-2012


【解决方案1】:

好的,我将发布一些代码来帮助您入门。首先你需要监听TextChanged 事件。

textBox1.TextChanged += new EventHandler(textBox1_TextChanged);

你需要在类中声明一个堆栈

 Stack<string> undoList = new Stack<string>();

在文本更改处理程序中,您需要将文本框的内容添加到堆栈中

 void textBox1_TextChanged(object sender, EventArgs e)
    {
        undoList.Push(textBox1.Text);
    }

然后你需要处理撤销,所以你可以简单地使用 CTRL-Z

 textBox1.KeyDown += new KeyEventHandler(textBox1_KeyDown);

void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
         if(e.KeyCode == Keys.Z && (e.Control)) {
             textBox1.Text = undoList.Pop();
         }
    }

【讨论】:

  • 您还可以检查是否undoList.Count &gt; 0 并将文本框的文本设置为空字符串,以避免在您一直撤消到开头时出现空堆栈错误。
  • 我发现这段代码有一个问题。也许我做错了,但在事件处理程序中,我发现我必须两次弹出文本框列表,因为。 texchanged 函数也被触发了
  • 我在代码中发现了一些有趣的东西。如果我将此应用于按钮,例如重做按钮。我必须弹出它两次,因为 textchanged 正在被触发
  • 这不起作用:Push 添加最后一个文本,因此它不会在弹出时撤消...并且当在 KeyDown 中分配文本时,会调用 TextChanged 事件。
  • 这不起作用:Push 添加最后一个文本,因此它不会在弹出时撤消...并且当在 KeyDown 中分配文本时,会调用 TextChanged 事件。 How to implement good and efficient undo/redo functionality for a TextBox (My attempt is here)
【解决方案2】:

您可以让 RichTextBox 为您逐字构建撤消堆栈,并跟踪插入符号的位置,方法是像这样处理 KeyDown-、KeyPress- 或 KeyUp 事件之一:

 private void rtb_KeyDown(object sender, KeyEventArgs e)
    {
        // Trick to build undo stack word by word
        RichTextBox rtb = (RichTextBox)sender;
        if (e.KeyCode == Keys.Space)
        {
            this.SuspendLayout();
            rtb.Undo();
            rtb.Redo();
            this.ResumeLayout();
        }
        // eztnap
    }

由于 RichTextBox 为您完成这项工作,您只需在需要的任何地方致电 rtb.Undo()rtb.Redo()

【讨论】:

  • 请注意,您可能还需要考虑其他空格(如制表符等)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-28
  • 1970-01-01
  • 1970-01-01
  • 2021-05-23
  • 2017-12-29
  • 1970-01-01
相关资源
最近更新 更多