Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何让RichTextBox Undo更好地工作?_C#_Winforms_Richtextbox_Undo_Redo - Fatal编程技术网

C# 如何让RichTextBox Undo更好地工作?

C# 如何让RichTextBox Undo更好地工作?,c#,winforms,richtextbox,undo,redo,C#,Winforms,Richtextbox,Undo,Redo,我正在尝试使用RichTextBox编写一个文本编辑器。我现在关心的是RichTextBox的撤销和重做功能 当我开始在文本框中写作时,说1分钟!若我调用Undo方法,它所做的只是再次清除或重置richtextbox。我怎样才能让它工作,它可以做得更好,像撤消最后添加的单词,或最后添加的新行…我的意思是通常的事情,你们期望从撤消功能。(重做的计数也相同!) 是否有属性或一些选项来实现这一点?或者我必须实现自己的代码 您可以保存最新的数据,当您想要撤消时,可以将“现在数据”更改为“最后数据”!可以

我正在尝试使用
RichTextBox
编写一个文本编辑器。我现在关心的是RichTextBox的撤销和重做功能

当我开始在文本框中写作时,说1分钟!若我调用
Undo
方法,它所做的只是再次清除或重置richtextbox。我怎样才能让它工作,它可以做得更好,像撤消最后添加的单词,或最后添加的新行…我的意思是通常的事情,你们期望从撤消功能。(重做的计数也相同!)


是否有属性或一些选项来实现这一点?或者我必须实现自己的代码

您可以保存最新的数据,当您想要撤消时,可以将“现在数据”更改为“最后数据”!可以随时设置最新数据

我制作了一个winForm,其中包含一个richTextBox和一个按钮,该按钮用于撤消写入的文本:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace test
{


public partial class Form1 : Form
{
    List<string> LastData = new List<string>();

    int undoCount = 0;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        LastData.Add(richTextBox1.Text);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            richTextBox1.Text = LastData[LastData.Count - undoCount - 1];
            ++undoCount;
        }
        catch { }
    }

    private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        LastData.Add(richTextBox1.Text);
        undoCount = 0;
    }
}
}
保存生词或新行的步骤

更新:
如果您想保存Ram,可以在多次撤消保存后删除列表中的第一个数据。

仅从ahmadali的代码继续,您可以将其放入单独的类中,并实现重做功能:

注意。是的,每次更改文本框时,它都会保存所有文本,因此,如果您的应用程序将用于大量文本,或者应用程序将延长打开时间(即天/周),您可以更改


公共类撤消器
{
受保护的System.Windows.Forms.RichTextBox txtBox;
受保护列表LastData=新列表();
受保护的int undoCount=0;
受保护的bool撤消=错误;
受保护的布尔重做=假;
公共撤消器(参考System.Windows.Forms.RichTextBox txtBox)
{
this.txtBox=txtBox;
添加(txtBox.Text);
}
public void undo_单击(对象发送方,事件参数e)
{
这个。撤销();
}
公共无效重做单击(对象发送者,事件参数e)
{
这个。重做();
}
公共作废撤消()
{
尝试
{
撤销=正确;
++撤消计数;
Text=LastData[LastData.Count-undoCount-1];
}
捕获{}
最后{this.undoing=false;}
}
公共无效重做()
{
尝试
{
如果(undoCount==0)
返回;
重做=真;
--撤消计数;
Text=LastData[LastData.Count-undoCount-1];
}
捕获{}
最后{this.redoing=false;}
}
公共作废保存()
{
如果(撤消| |重做)
返回;
if(LastData[LastData.Count-1]==txtBox.Text)
返回;
添加(txtBox.Text);
撤消计数=0;
}
}

我不明白,你能举一些代码示例吗?我想问的是,在我的应用程序处于活动状态并且用户更改了文本的情况下,如何才能获得撤销点。谢谢,但是……这是一项棘手的工作!如果用户处理大量文本,您不认为这个列表会变得非常大吗?如果这是唯一的方法,那么每隔一段时间添加一个计时器并保存内容也是一个好主意。@Sean87:它用于多次撤消(而不是一次),但如果您只想撤消一次,则可以使用字符串,而不是使用列表来撤消lastdata!
LastData.Add(richTextBox1.Text);
undoCount = 0;
public partial class MainForm : Form
{

    Undoer undoer;

    public MainForm()
    {
        InitializeComponent();

        this.txtBox.TextChanged += new EventHandler( TextBoxTextChanged );
        this.undoer = new Undoer(ref this.txtText);


        // create a context menu
        ContextMenu menu = new ContextMenu();
        menu.MenuItems.AddRange( new MenuItem[] { 
                    new MenuItem("&Undo",  new EventHandler( this.undoer.undo_Click  )),
                    new MenuItem("&Redo",  new EventHandler( this.undoer.redo_Click  ))
        });
        this.txtBox.ContextMenu = menu;

        // or create keypress event 
        this.txtBox.KeyDown += new KeyEventHandler( textBox_KeyDown );
        this.KeyDown  += new KeyEventHandler( textBox_KeyDown );
    }

    protected void TextBoxTextChanged(object sender, EventArgs e)
    {
        undoer.Save();
    }

    protected void textBox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
    {
        if (e.Modifiers == (System.Windows.Forms.Keys.Control))
        {
            if ( e.KeyCode == Keys.Z )
            {
                this.undoer.Undo();
                e.Handled = true;
            }
            if ( e.KeyCode == Keys.Y )
            {
                this.undoer.Redo();
                e.Handled = true;
            }
        }
    }
}
public class Undoer
{
    protected System.Windows.Forms.RichTextBox txtBox;
    protected List<string> LastData = new List<string>();
    protected int  undoCount = 0;

    protected bool undoing   = false;
    protected bool redoing   = false;


    public Undoer(ref System.Windows.Forms.RichTextBox txtBox)
    {
        this.txtBox = txtBox;
        LastData.Add(txtBox.Text);
    }

    public void undo_Click(object sender, EventArgs e)
    {
        this.Undo();
    }
    public void redo_Click(object sender, EventArgs e)
    {
        this.Redo();
    }

    public void Undo()
    {
        try
        {
            undoing = true;
            ++undoCount;
            txtBox.Text = LastData[LastData.Count - undoCount - 1];
        }
        catch { }
        finally{ this.undoing = false; }
    }
    public void Redo()
    {
        try
        {
            if (undoCount == 0)
                return;

            redoing = true;
            --undoCount;
            txtBox.Text = LastData[LastData.Count - undoCount - 1];
        }
        catch { }
        finally{ this.redoing = false; }
    }

    public void Save()
    {
        if (undoing || redoing)
            return;

        if (LastData[LastData.Count - 1] == txtBox.Text)
            return;

        LastData.Add(txtBox.Text);
        undoCount = 0;
    }
}