箇条書きの設定をおこない、これを複数のRichTextBoxで同期させます。
RichTextBoxの選択されている部分を箇条書きスタイルにするかどうかはSelectionBulletプロパティを使えばできます。そこで処理前の状態と処理後の状態を保存しておけば、Undo、Redoにも対応できます。
ではさっそくやってみましょう。
SelectionBulletプロパティを設定するときも行頭の文字の位置を取得してここにカーソルを移動して設定しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
internal class BulletInfo { internal BulletInfo(int charIndex, bool oldBullet, bool newBullet) { CharIndex = charIndex; NewBullet = newBullet; OldBullet = oldBullet; } internal int CharIndex { get; } = 0; internal bool NewBullet { get; } = false; internal bool OldBullet { get; } = false; } |
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 |
public class Undobuf { List<BulletInfo> _bulletInfos = null; internal List<BulletInfo> BulletInfos { get { if (_bulletInfos == null) return null; List<BulletInfo> ret = new List<BulletInfo>(); if (IsUndo) { foreach (var info in _bulletInfos) { ret.Add(new BulletInfo(info.CharIndex, info.NewBullet, info.OldBullet)); } } else { foreach (var info in _bulletInfos) { ret.Add(info); } } return ret; } set { _bulletInfos = value; } } } |
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 |
public partial class SyncRichTextBox : UserControl { void SetBullet(bool bullet) { List<int> vs = GetSelectedLineHeads(); int start = vs.Min(); int len = GetSelectedLineTail() - start; SelectionStart = start; SelectionLength = len; Undobuf buf = new Undobuf(); buf.oldSelectionLength = len; buf.newSelectionLength = len; buf.oldSelectionStart = start; buf.newSelectionStart = start; List<BulletInfo> bulletInfos = new List<BulletInfo>(); foreach (int index in vs) { richTextBoxEx1.Select(index, 0); bool oldBullet = richTextBoxEx1.SelectionBullet; bool newBullet = bullet; bulletInfos.Add(new BulletInfo(index, oldBullet, newBullet)); } if (!bulletInfos.Any(x => x.OldBullet != x.NewBullet)) return; buf.BulletInfos = bulletInfos; buf.action = "SelectionBullet"; if (SetBullet(buf)) Data.InsertUndobuf(buf); } bool SetBullet(Undobuf buf) { foreach (var sync in Data.SyncRichTextBoxes) { var info = Data.GetRichTextBoxInfo(sync); if (info != null) info.SelectionStart = sync.richTextBoxEx1.SelectionStart; } OnTextChanging(buf); if (buf.IsCancel) return false; foreach (var rich in Data.SyncRichTextBoxes) { var info = Data.GetRichTextBoxInfo(rich); int oldStart = info.SelectionStart; foreach (BulletInfo info1 in buf.BulletInfos) { if (rich.Data == Data) { rich.richTextBoxEx1.Select(info1.CharIndex, 0); rich.richTextBoxEx1.SelectionBullet = info1.NewBullet; } } if (rich == this) { rich.SelectionStart = buf.NewSelectionStart; rich.SelectionLength = buf.NewSelectionLength; } else if (rich != this && rich.Data == Data) { rich.SelectionStart = oldStart; rich.SelectionLength = 0; } } return true; } public bool SelectionBullet { get { return richTextBoxEx1.SelectionBullet; } set { SetBullet(value); } } } |
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 |
public partial class SyncRichTextBox : UserControl { public void Undo() { var buf = Data.GetUndobuf(); if (buf == null) return; buf.IsUndo = true; // その他の処理は省略 if (buf.BulletInfos != null) SetBullet(buf); buf.IsUndo = false; Data.MoveToRedobufs(); } public void Redo() { var buf = Data.GetRedobuf(); if (buf == null) return; // その他の処理は省略 if (buf.BulletInfos != null) SetBullet(buf); Data.MoveToUndobufs(); } } |