现在的位置: 首页 > 综合 > 正文

可以进行多步撤消(Undo、Redo)的TextBox

2013年09月08日 ⁄ 综合 ⁄ 共 2193字 ⁄ 字号 评论关闭

 

默认的TextBox只能进行一步撤消,且不存在Redo操作(二次撤消相当于一次Redo)。以下这个组件实现了TextBox的多步撤消(Undo、Redo)操作,代码改编于Kevin.SyntaxTextBox(原代码是针对RichTextBox实现的Undo、Redo功能)。 
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Ekinglong.Drawing.Forms
{
    /// <summary> 
    /// 可以执行多步撤消操作的TextBox 
    /// </summary> 
    public partial class TextBoxEx : TextBox
    {
        //Undo/Redo members 
        private List<UndoRedoInfo> mUndoList = new List<UndoRedoInfo>();
        private Stack<UndoRedoInfo> mRedoStack = new Stack<UndoRedoInfo>();
        private bool mIsUndo = false;
        private UndoRedoInfo mLastInfo = new UndoRedoInfo("", 0);
        private int mMaxUndoRedoSteps = 50;

        /// <summary> 
        /// The on text changed overrided. 
        /// </summary> 
        /// <param name="e"> </param> 
        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);

            if (!mIsUndo)
            {
                mRedoStack.Clear();
                mUndoList.Insert(0, mLastInfo);
                this.LimitUndo();
                mLastInfo = new UndoRedoInfo(Text, SelectionStart);
            }
            //Invalidate(); 
        }

        /// <summary> 
        /// 设置和获取撤消操作允许的最大步数 
        /// </summary> 
        public int MaxUndoRedoSteps
        {
            set { mMaxUndoRedoSteps = value; }
            get { return mMaxUndoRedoSteps; }
        }
        /// <summary> 
        /// 清空Undo、Redo操作信息 
        /// </summary> 
        public void ClearUndoAndRedo()
        {
            mUndoList.Clear();
            mRedoStack.Clear();
        }
        /// <summary> 
        /// 判断是否可以进行Undo操作 
        /// </summary> 
        public new bool CanUndo
        {
            get { return mUndoList.Count > 0; }
        }
        /// <summary> 
        /// 判断是否可以进行Redo操作 
        /// </summary> 
        public bool CanRedo
        {
            get { return mRedoStack.Count > 0; }
        }
        /// <summary> 
        /// 撤消操作 
        /// </summary> 
        public new void Undo()
        {
            if (!CanUndo)
                return;
            mIsUndo = true;
            mRedoStack.Push(new UndoRedoInfo(Text, SelectionStart));
            UndoRedoInfo info = (UndoRedoInfo) mUndoList[0];
            mUndoList.RemoveAt(0);
            Text = info.Text;
            SelectionStart = info.CursorLocation;
            ScrollToCaret();
            mLastInfo = info;
            mIsUndo = false;
        }
        /// <summary> 
        /// 重复操作 
        /// </summary> 
        public void Redo()
        {
            if (!CanRedo)
                return;
            mIsUndo = true;
            mUndoList.Insert(0, new UndoRedoInfo(Text, SelectionStart));
            LimitUndo();
            UndoRedoInfo info = (UndoRedoInfo) mRedoStack.Pop();
            Text = info.Text;
            SelectionStart = info.CursorLocation;
            ScrollToCaret();
            mIsUndo = false;
        }
        private void LimitUndo()
        {
            while (mUndoList.Count > mMaxUndoRedoSteps)
            {
                mUndoList.RemoveAt(mMaxUndoRedoSteps);
            }
        }

        private class UndoRedoInfo
        {
            public UndoRedoInfo(string text, int cursorLoc)
            {
                Text = text;
                CursorLocation = cursorLoc;
            }
            public readonly int CursorLocation;
            public readonly string Text;
        }
    }
}
http://www.chenjiliang.com/Article/View.aspx?ArticleID=19079

抱歉!评论已关闭.