Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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# 如何在TextBox中实现自定义撤消_C#_.net_Winforms - Fatal编程技术网

C# 如何在TextBox中实现自定义撤消

C# 如何在TextBox中实现自定义撤消,c#,.net,winforms,C#,.net,Winforms,我想为文本框手动实现一个基本的撤销系统(因为中提到的问题)。我已经试了好几个小时了,但是我找不到办法。有人知道这是否可能吗 例如,这样做似乎需要检测到用户改变了插入符号的位置,但我不知道如何做到这一点。当然,我可以听到箭头键,并检测鼠标点击,但似乎不可能——至少在箭头键的情况下——真正说出SelectionStart是否已更改 如果有人有任何想法,我将不胜感激 汤姆这有点老了,但听起来和你需要的一模一样: 总而言之,在替换选项卡时,只需选择框中的所有文本并添加4个空格,然后将整个文本粘贴回框中

我想为文本框手动实现一个基本的撤销系统(因为中提到的问题)。我已经试了好几个小时了,但是我找不到办法。有人知道这是否可能吗

例如,这样做似乎需要检测到用户改变了插入符号的位置,但我不知道如何做到这一点。当然,我可以听到箭头键,并检测鼠标点击,但似乎不可能——至少在箭头键的情况下——真正说出SelectionStart是否已更改

如果有人有任何想法,我将不胜感激


汤姆

这有点老了,但听起来和你需要的一模一样:

总而言之,在替换选项卡时,只需选择框中的所有文本并添加4个空格,然后将整个文本粘贴回框中


这应该允许用户点击ctrl+z来撤销整个操作。现在,我不知道如果他们在做空格后继续打字会发生什么。。。我假设它将从ctrl+z组合键中全部删除。

这有点旧,但听起来与您需要的完全一样:

总而言之,在替换选项卡时,只需选择框中的所有文本并添加4个空格,然后将整个文本粘贴回框中


这应该允许用户点击ctrl+z来撤销整个操作。现在,我不知道如果他们在做空格后继续打字会发生什么。。。我假设它会从ctrl+z组合键中删除。

您能否处理
TextChanged
事件,并在每次更改时将文本框内容推到堆栈上,然后每次用户点击Ctrl-Z时弹出并刷新
TextBox

你能处理
TextChanged
事件吗?每次它发生变化时,只需将TextBox内容推到堆栈上,然后每次用户点击Ctrl-Z时弹出并刷新
TextBox

这是我开发的解决方案,对我来说效果很好:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace INQ_adm.Forms.ControlsX
{
    public class TextBoxX : TextBox
    {
        private static int UNDO_LIMIT = 0;
        private List<Item> LastData = new List<Item>();
        private int undoCount = 0;
        private Boolean undo = false;

        public TextBoxX()
        {
            InitializeComponent();
        }

       protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == (Keys.Control | Keys.Z))
            {
                undo = true;
                try
                {
                    ++undoCount;
                    this.Text = LastData[LastData.Count - undoCount - 1].text;
                    this.SelectionStart = LastData[LastData.Count - undoCount - 1].position;
                    this.PerformLayout();
                }
                catch
                {
                    --undoCount;
                }

                undo = false;
                return true;
            }

            if (keyData == (Keys.Control | Keys.Y))
            {
                undo = true;
                try
                {
                    --undoCount;
                    this.Text = LastData[LastData.Count - undoCount + 1].text;
                    this.SelectionStart = LastData[LastData.Count - undoCount + 1].position;
                    this.PerformLayout();
                }
                catch
                {
                    ++undoCount;
                }

                undo = false;
                return true;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void textBoxX_TextChanged(object sender, EventArgs e)
        {
            if (!undo)
            {
                LastData.RemoveRange(LastData.Count - undoCount, undoCount);
                LastData.Add(new Item(this.Text, this.SelectionStart));
                undoCount = 0;
                    if (UNDO_LIMIT != 0 && UNDO_LIMIT + 1 < LastData.Count)
                {
                    LastData.RemoveAt(0);
                }
            }
        }

        private void InitializeComponent()
        {
            this.TextChanged += new System.EventHandler(this.textBoxX_TextChanged);
        }
    }

    public class Item
    {
        public String text;
        public int position;

        public Item(String text, int position)
        {
            this.text = text;
            this.position = position;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
命名空间INQ_adm.Forms.ControlsX
{
公共类TextBoxX:TextBox
{
私有静态int UNDO_LIMIT=0;
私有列表LastData=新列表();
私有计数=0;
私有布尔撤消=false;
公共TextBoxX()
{
初始化组件();
}
受保护的覆盖bool ProcessCmdKey(参考消息消息消息,Keys keyData)
{
if(keyData==(Keys.Control | Keys.Z))
{
撤销=真;
尝试
{
++撤消计数;
this.Text=LastData[LastData.Count-undoCount-1].Text;
this.SelectionStart=LastData[LastData.Count-undoCount-1]。位置;
这个。执行布局();
}
接住
{
--撤消计数;
}
撤销=假;
返回true;
}
if(keyData==(Keys.Control | Keys.Y))
{
撤销=真;
尝试
{
--撤消计数;
this.Text=LastData[LastData.Count-undoCount+1].Text;
this.SelectionStart=LastData[LastData.Count-undoCount+1]。位置;
这个。执行布局();
}
接住
{
++撤消计数;
}
撤销=假;
返回true;
}
返回base.ProcessCmdKey(ref msg,keyData);
}
私有void textBoxX_TextChanged(对象发送方,事件参数e)
{
如果(!撤消)
{
RemoveRange(LastData.Count-undoCount,undoCount);
添加(新项(this.Text,this.SelectionStart));
撤消计数=0;
如果(撤消限制!=0&&撤消限制+1
这是我开发的解决方案,对我来说效果很好:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace INQ_adm.Forms.ControlsX
{
    public class TextBoxX : TextBox
    {
        private static int UNDO_LIMIT = 0;
        private List<Item> LastData = new List<Item>();
        private int undoCount = 0;
        private Boolean undo = false;

        public TextBoxX()
        {
            InitializeComponent();
        }

       protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == (Keys.Control | Keys.Z))
            {
                undo = true;
                try
                {
                    ++undoCount;
                    this.Text = LastData[LastData.Count - undoCount - 1].text;
                    this.SelectionStart = LastData[LastData.Count - undoCount - 1].position;
                    this.PerformLayout();
                }
                catch
                {
                    --undoCount;
                }

                undo = false;
                return true;
            }

            if (keyData == (Keys.Control | Keys.Y))
            {
                undo = true;
                try
                {
                    --undoCount;
                    this.Text = LastData[LastData.Count - undoCount + 1].text;
                    this.SelectionStart = LastData[LastData.Count - undoCount + 1].position;
                    this.PerformLayout();
                }
                catch
                {
                    ++undoCount;
                }

                undo = false;
                return true;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void textBoxX_TextChanged(object sender, EventArgs e)
        {
            if (!undo)
            {
                LastData.RemoveRange(LastData.Count - undoCount, undoCount);
                LastData.Add(new Item(this.Text, this.SelectionStart));
                undoCount = 0;
                    if (UNDO_LIMIT != 0 && UNDO_LIMIT + 1 < LastData.Count)
                {
                    LastData.RemoveAt(0);
                }
            }
        }

        private void InitializeComponent()
        {
            this.TextChanged += new System.EventHandler(this.textBoxX_TextChanged);
        }
    }

    public class Item
    {
        public String text;
        public int position;

        public Item(String text, int position)
        {
            this.text = text;
            this.position = position;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
命名空间INQ_adm.Forms.ControlsX
{
公共类TextBoxX:TextBox
{
私有静态int UNDO_LIMIT=0;
私有列表LastData=新列表();
私有计数=0;
私有布尔撤消=false;
公共TextBoxX()
{
初始化组件();
}
受保护的覆盖bool ProcessCmdKey(参考消息消息消息,Keys keyData)
{
if(keyData==(Keys.Control | Keys.Z))
{
撤销=真;
尝试
{
++撤消计数;
this.Text=LastData[LastData.Count-undoCount-1].Text;
this.SelectionStart=LastData[LastData.Count-undoCount-1]。位置;
这个。执行布局();
}
接住
{
--撤消计数;
}
撤销=假;
返回true;
}
if(keyData==(Keys.Control | Keys.Y))
{
撤销=真;
尝试
{
--撤消计数;
this.Text=LastData[LastData.Count-undoCount+1].Text;