我使用KeyPress事件以编程方式在自定义RichTextBox中添加文本:
SelectedText = e.KeyChar.ToString();
问题是以这种方式插入文本不会触发CanUndo标志。
因此,当我尝试撤消/重做文本时(通过调用文本框的Undo()和Redo()方法),没有任何反应。
我尝试以编程方式从TextChanged()事件中唤起KeyUp()事件,但仍未将CanUndo标记为true。
如何撤消插入的文本而不必为撤消和重做操作创建列表?
由于
答案 0 :(得分:3)
我最终决定使用堆栈创建自己的undo-redo系统。
以下是我如何做到的快速概述:
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();
}
答案 1 :(得分:1)
这只是一个想法,但如果您将插入位置设置为插入文本的位置而不是修改Text属性,只需send the keys?
SendKeys.Send("The keys I want to send");
肯定会有怪癖,但正如我所说,这只是一个想法。
答案 2 :(得分:0)
您可以使用TestBox.Paste。 class overview中的文档说“将所选文本设置为指定文本而不清除撤消缓冲区。”,似乎令人困惑。我刚试过它并按预期设置了撤销。
尽管它的名称与剪贴板完全没有关系,它只是用您提供的文本替换当前选择的文本作为参数,因此似乎只是以非常简单的方式执行问题所要求的。