Я создал свою собственную систему отмены для RichTextBox, в которой всякий раз, когда вы что-то делаете, в стек добавляется действие отмены, а когда вы нажимаете отмену, это действие отменяется.
Это поведение прекрасно работает со всеми элементами управления, для которых я его реализовал, за исключением RichTextBoxes. Я сократил систему до ее самых простых элементов, где всякий раз, когда вы нажимаете кнопку удаления, она добавляет текущий выбранный текст и его индекс в стек, а когда вы отменяете это, он помещает текст обратно в этот индекс.
Вот код с наиболее простыми элементами (такими как фактическое чтение текстового файла):
// Struct I use to store undo data
public struct UndoSection
{
public string Undo;
public int Index;
public UndoSection(int index, string undo)
{
Index = index;
Undo = undo;
}
}
public partial class Form1 : Form
{
// Stack for holding Undo Data
Stack<UndoSection> UndoStack = new Stack<UndoSection>();
// If delete is pressed, add a new UndoSection, if ctrl+z is pressed, peform undo.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.None && e.KeyCode == Keys.Delete)
UndoStack.Push(new UndoSection(textBox1.SelectionStart, textBox1.SelectedText));
else if (e.Control && e.KeyCode == Keys.Z)
{
e.Handled = true;
UndoMenuItem_Click(textBox1, new EventArgs());
}
}
// Perform undo by setting selected text at stored index.
private void UndoMenuItem_Click(object sender, EventArgs e)
{
if (UndoStack.Count > 0)
{
// Save last selection for user
int LastStart = textBox1.SelectionStart;
int LastLength = textBox1.SelectionLength;
UndoSection Undo = UndoStack.Pop();
textBox1.Select(Undo.Index, 0);
textBox1.SelectedText = Undo.Undo;
textBox1.Select(LastStart, LastLength);
}
}
}
Однако, если вы выберете только \ n из одной строки и больше текста ниже, например: , затем нажмите «Удалить», а затем отменить, кажется, этот \ n символ дважды отменяется.