今回はRichTextEditorの編集履歴をとります。
UndoしてRedoして、こんなことを繰り返して自分がどこにいるのかわからなくなった・・・なんて経験はないでしょうか? そこで編集履歴をとることで自分がどこにいるのか、Undoバッファのなかで迷子にならないようにするためのアプリを作成しました。
使用するのは
s
これでつかったSyncRichTextBoxクラスです。
まずUndoバッファとRedoバッファが格納されているリストを取得します。このときリスト内のデータが改ざんされないようにコピーを取得するようにします。
1 2 3 4 5 6 7 8 9 10 11 |
public partial class SyncRichTextBox : UserControl { public List<Undobuf> GetUndobufs() { return Data.GetUndobufs().ToList(); // データが改ざんされるのを防ぐ } public List<Undobuf> GetRedobufs() { return Data.GetRedobufs().ToList(); // データが改ざんされるのを防ぐ } } |
UndoバッファとRedoバッファをそれぞれ取得することができたら、これをListViewに表示します。
見た目はこんな感じ。
メニューがクリックされたら
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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
public partial class Form1 : Form { private void showRichTextEditHistoryToolStripMenuItem_Click(object sender, EventArgs e) { ShowRichTextBoxHistory(); } void ShowRichTextBoxHistory() { EditHistoryForm form2 = new EditHistoryForm(); form2.listView1.Items.Clear(); var undobufs = syncRichTextBoxEx1.GetUndobufs(); foreach (Undobuf buf in undobufs) { List<string> strs = new List<string>(); DateTime EditTime = buf.EditTime; string strEditTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", EditTime.Hour, EditTime.Minute, EditTime.Second, EditTime.Millisecond); strs.Add(strEditTime); strs.Add(buf.Action); if (buf.RemoveLength != 0) { strs.Add(buf.RemoveStart.ToString()); strs.Add(buf.RemoveLength.ToString()); strs.Add(buf.RemoveText); } else { strs.Add("-"); strs.Add("-"); strs.Add("-"); } if (buf.InsertLength != 0) { strs.Add(buf.InsertStart.ToString()); strs.Add(buf.InsertLength.ToString()); strs.Add(buf.InsertText); } else { strs.Add("-"); strs.Add("-"); strs.Add("-"); } ListViewItem item = new ListViewItem(strs.ToArray()); RichEditedInfo o = new RichEditedInfo(buf.RemoveText, buf.InsertText); item.Tag = o; form2.listView1.Items.Add(item); } var redobufs = syncRichTextBoxEx1.GetRedobufs(); foreach (Undobuf buf in redobufs) { List<string> strs = new List<string>(); DateTime EditTime = buf.EditTime; string strEditTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", EditTime.Hour, EditTime.Minute, EditTime.Second, EditTime.Millisecond); strs.Add(strEditTime); strs.Add(buf.Action); if (buf.RemoveLength != 0) { strs.Add(buf.RemoveStart.ToString()); strs.Add(buf.RemoveLength.ToString()); strs.Add(buf.RemoveText); } else { strs.Add("-"); strs.Add("-"); strs.Add("-"); } if (buf.InsertLength != 0) { strs.Add(buf.InsertStart.ToString()); strs.Add(buf.InsertLength.ToString()); strs.Add(buf.InsertText); } else { strs.Add("-"); strs.Add("-"); strs.Add("-"); } ListViewItem item = new ListViewItem(strs.ToArray()); RichEditedInfo o = new RichEditedInfo(buf.RemoveText, buf.InsertText); item.Tag = o; form2.listView2.Items.Add(item); } form2.ShowDialog(); } } |
1 2 3 4 5 6 7 8 9 10 |
public class RichEditedInfo { public RichEditedInfo(string removeString, string insertString) { RemoveString = removeString; InsertString = insertString; } public string RemoveString { get; } public string InsertString { get; } } |
みてわかるように削除、追加された文字列が存在しない場合は「-」を表示させています。そしてリストの項目がクリックされたら削除された文字列と追加された文字列を表示させることができるようにRichEditedInfoクラスのオブジェクトをリストアイテムのTagプロパティにセットしています。
あとはリストの項目がクリックされたら削除された文字列と追加された文字列を表示させ、直前や直後にどのような操作をしたのかユーザーにわかるように示します。
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 partial class EditHistoryForm : Form { public EditHistoryForm() { InitializeComponent(); } private void listView1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) { if (e.Item != null && e.IsSelected) { RichEditedInfo info = (RichEditedInfo)e.Item.Tag; richTextBox1.Text = info.InsertString; richTextBox2.Text = info.RemoveString; foreach (ListViewItem a in listView2.SelectedItems) a.Selected = false; } } private void listView2_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) { if (e.Item != null && e.IsSelected) { RichEditedInfo info = (RichEditedInfo)e.Item.Tag; richTextBox1.Text = info.InsertString; richTextBox2.Text = info.RemoveString; foreach (ListViewItem a in listView1.SelectedItems) a.Selected = false; } } } |
では、さっそく編集履歴がどのように表示されるのかみてみましょう。
「ぷとぐらみんぐは」とありますが、「ぷとぐらみんぐ」って何でしょうか。入力ミスに気づいてUndoを実行したところであることがわかります。