6

我正在使用 KeyPress 事件以编程方式在自定义 RichTextBox 中添加文本:

SelectedText = e.KeyChar.ToString(); 

问题在于以这种方式插入文本不会触发 CanUndo 标志。

因此,当我尝试撤消/重做文本(通过调用文本框的 Undo() 和 Redo() 方法)时,什么也没有发生。

我尝试以编程方式从 TextChanged() 事件中调用 KeyUp() 事件,但这仍然没有将 CanUndo 标记为 true。

如何撤消插入的文本,而无需为撤消和重做操作创建列表?

谢谢

4

3 回答 3

3

我最终决定使用堆栈创建自己的撤消重做系统。

这是我如何做到的快速概述:

private const int InitialStackSize = 500;    
private Stack<String> undoStack = new Stack<String>(InitialStackSize);
private Stack<String> redoStack = new Stack<String>(InitialStackSize); 

private void YourKeyPressEventHandler(...)
{
        // The user pressed on CTRL - Z, execute an "Undo"
        if (e.KeyChar == 26)
        {
            // Save the cursor's position
            int selectionStartBackup = SelectionStart;

            redoStack.Push(Text);
            Text = undoStack.Pop();

            // Restore the cursor's position
            SelectionStart = selectionStartBackup;
        }
        // The user pressed on CTRL - Y, execute a "Redo"
        if (e.KeyChar == 25)
        {
            if (redoStack.Count <= 0)
                return;

            // Save the cursor's position
            int selectionStartBackup = SelectionStart + redoStack.ElementAt(redoStack.Count - 1).Length;

            undoStack.Push(Text);
            Text = redoStack.Pop();

            // Restore the cursor's position
            SelectionStart = selectionStartBackup;

            return;
        }    

        undoStack.Push(Text);
        SelectedText = e.KeyChar.ToString();  
}
于 2011-03-24T18:37:09.580 回答
1

这只是一个想法,但是如果将插入符号位置设置为插入文本的位置,而不是修改 Text 属性,只需发送键怎么办?

SendKeys.Send("The keys I want to send");

肯定会有怪癖,但正如我所说,这只是一个想法。

于 2011-03-24T15:57:17.547 回答
0

您可以使用TestBox.Paste类概述中的文档说“将选定的文本设置为指定的文本而不清除撤消缓冲区。”,似乎令人困惑。我刚刚尝试过,它按预期设置了撤消。

尽管它的名称与剪贴板完全无关,它只是用您作为参数提供的文本替换当前选择的文本,因此似乎只是以非常简单的方式执行问题所要求的。

于 2015-07-28T13:37:37.553 回答