[C#][轉載]實現richtextbox的多步撤消(Undo、Redo)?

下面是針對textbox的。高手參照此資料做一個richtextbox,
[C#]可以進行多步撤消(Undo、Redo)的TextBox 

默認的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;
         }
     }
 }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章