自作したSyncRichTextBoxクラスにアンドゥバッファに関する情報を表示させる機能を追加します。
SyncRichTextBoxが変更されたときのイベントとしてTextChangedExを作成します。SyncRichTextBoxが変更されたときというのは
RichData.InsertUndobufが実行されたとき
RichData.ClearUndobufが実行されたとき
SyncRichTextBox.Dataプロパティが変更されたとき
Undo、Redoが実行されたとき
です。
まずハンドラへ渡す引数を作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class TextChangedExArgs { RichData Data { get; } public TextChangedExArgs(RichData data) { Data = data; } public List<Undobuf> Redobufs { get { return Data.GetRedobufs().ToList(); } // 内容がかわらないようにコピーを渡す } public List<Undobuf> Undobufs { get { return Data.GetUndobufs().ToList(); } // 内容がかわらないようにコピーを渡す } } |
RichData.InsertUndobufが実行されたとき
RichData.ClearUndobufが実行されたとき
SyncRichTextBox.Dataプロパティが変更されたとき
Undo、Redoが実行されたとき
これらのときにイベントを発生させます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
public partial class SyncRichTextBox : UserControl { public delegate void TextChangedExHandler(SyncRichTextBox sender, TextChangedExArgs e); public event TextChangedExHandler TextChangedEx; public RichData Data { get { return _data; } set { // 省略 foreach (var rich in Data.SyncRichTextBoxes) rich.OnTextChanged(); } } public void Undo() { // Undo処理は正常におこなわれた Data.MoveToRedobufs(); foreach (var sync in Data.SyncRichTextBoxes) sync.OnTextChanged(); } public void Redo() { // Redo処理は正常におこなわれた Data.MoveToUndobufs(); foreach (var sync in Data.SyncRichTextBoxes) sync.OnTextChanged(); } internal void OnTextChanged() { TextChangedExArgs e = new TextChangedExArgs(Data); OnTextChanged(e); } protected virtual void OnTextChanged(TextChangedExArgs e) { TextChangedEx?.Invoke(this, e); } // 使うことはないので sealed する sealed protected override void OnTextChanged(EventArgs e) { base.OnTextChanged(e); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public class RichData { internal void InsertUndobuf(Undobuf buf) { _undobufs.Insert(0, buf); _redobufs.Clear(); foreach (var sync in SyncRichTextBoxes) { sync.OnTextChanged(); } } internal void ClearUndobuf(Undobuf buf) { _undobufs.Clear(); _redobufs.Clear(); foreach (var sync in SyncRichTextBoxes) { sync.OnTextChanged(); } } } |
アンドゥバッファの大きさを求めます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
public class Undobuf { int dataSize = 0; public int DataSize { get { if (dataSize != 0) return dataSize; var utf8 = System.Text.Encoding.UTF8; int removeRtfSize = utf8.GetByteCount(RemoveRtf); int insertRtfSize = utf8.GetByteCount(InsertRtf); int removeTextSize = utf8.GetByteCount(RemoveText); int insertTextSize = utf8.GetByteCount(InsertText); int indentInfosSize = 0; if (IndentInfos != null) indentInfosSize = IndentInfos.Count * sizeof(int) * 3; int tabInsertInfoSize = 0; if (tabInsertIndexes != null) tabInsertInfoSize = (tabInsertIndexes.Count + tabInsertIndexesUndo.Count) * sizeof(int); if (tabRemoveIndexes != null) tabInsertInfoSize += (tabRemoveIndexes.Count + tabRemoveIndexesUndo.Count) * sizeof(int); dataSize = removeRtfSize + insertRtfSize + removeTextSize + insertTextSize + tabInsertInfoSize + indentInfosSize + 100; return dataSize; } } } |
これでアンドゥバッファの状態が変わると通知されるので、その情報を表示させることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public partial class Form1 : Form { private void syncRichTextBoxEx1_TextChangedEx(SyncRichTextBox sender, TextChangedExArgs e) { int size = 0; foreach (var undobuf in e.Undobufs) size += undobuf.DataSize; foreach (var redobuf in e.Redobufs) size += redobuf.DataSize; label1.Text = String.Format("Undobufサイズは{0}Byte Undoは{1}回、Redoは{2}回 可能です", size, e.Undobufs.Count, e.Redobufs.Count); } } |