C# RichTextBox撤消添加空格

C# RichTextBox撤消添加空格,c#,winforms,c#-4.0,richtextbox,undo,C#,Winforms,C# 4.0,Richtextbox,Undo,我已经为RichTextBox创建了自己的撤消系统,每当您执行某项操作时,就会将撤消操作添加到堆栈中,当您按下撤消时,该操作就会撤消 除了RichTextBox之外,这个行为在我实现它的所有控件中都非常有效。我将系统简化为最简单的元素,每当您按delete键时,它会将当前选定的文本及其索引添加到堆栈中,当您撤消此操作时,它会将文本放回此索引 下面是去掉最简单元素的代码(如文本文件的实际读取): //用于存储撤消数据的结构 公共结构撤消部分 { 公共字符串撤消; 公共整数指数; 公共撤消部分(整型

我已经为RichTextBox创建了自己的撤消系统,每当您执行某项操作时,就会将撤消操作添加到堆栈中,当您按下撤消时,该操作就会撤消

除了RichTextBox之外,这个行为在我实现它的所有控件中都非常有效。我将系统简化为最简单的元素,每当您按delete键时,它会将当前选定的文本及其索引添加到堆栈中,当您撤消此操作时,它会将文本放回此索引

下面是去掉最简单元素的代码(如文本文件的实际读取):

//用于存储撤消数据的结构
公共结构撤消部分
{
公共字符串撤消;
公共整数指数;
公共撤消部分(整型索引、字符串撤消)
{
指数=指数;
撤消=撤消;
}
}
公共部分类Form1:Form
{
//用于保存撤消数据的堆栈
Stack UndoStack=新堆栈();
//如果按delete键,则添加一个新的UndoSection;如果按ctrl+z键,则执行“撤消”。
私有void Form1\u KeyDown(对象发送方,KeyEventArgs e)
{
if(e.Modifiers==Keys.None&&e.KeyCode==Keys.Delete)
UndoStack.Push(新的undossection(textBox1.SelectionStart,textBox1.SelectedText));
else if(e.Control&&e.KeyCode==Keys.Z)
{
e、 已处理=正确;
UndoMenuItem_单击(textBox1,new EventArgs());
}
}
//通过在存储索引处设置选定文本来执行撤消。
私有void UndoMenuItem\u单击(对象发送者,事件参数e)
{
如果(UndoStack.Count>0)
{
//为用户保存上次选择
int LastStart=textBox1.SelectionStart;
int LastLength=textBox1.SelectionLength;
UndoSection Undo=UndoStack.Pop();
textBox1.选择(Undo.Index,0);
textBox1.SelectedText=Undo.Undo;
textBox1.选择(LastStart,LastLength);
}
}
}

但是,如果您仅从一行中选择\n,然后按delete键,然后按undo键,则此字符似乎会被撤消两次。

我已经设置了此代码,并且它似乎可以使用textbox和richtextbox执行您希望它为我执行的操作,我无法获得要删除或添加的额外空间。是否有一个特定的操作顺序,我可以尝试重新创建您的问题?

我想我已经解决了。当您高亮显示这样的文本时:您还可以在我指向的最后一行末尾包含\n字符。但是,当您按delete键时,RTB实际上不会删除此字符。因此,在撤消删除操作时,必须删除所有尾随字符,\n因为它们实际上没有被删除。

我终于找到了问题的原因,而不是解决方案:当您使用前一行中的\n字符开始选择时,删除选择,然后撤消该选择,不知何故,该\n被添加了两次。是否已逐步完成代码?可能,将堆栈上的所有内容输出到某个位置,然后重新填充堆栈?
// 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);
        }
    }
}