RichTextBox.SelectionAlignmentプロパティを設定することで「中央揃え」「左揃え」「右揃え」が可能です。同期されたRichTextBoxでこの処理をやってみましょう。
アンドゥバッファは自前で用意するのでUndoで元に戻せるように以前の状態を記憶する必要があります。選択されている部分がふくまれる行の行頭を取得する必要があります。
ここで作成した GetSelectedLineHeadsメソッドが使えそうです。選択されている部分がふくまれる行をまるまる選択状態にするために GetSelectedLineTail メソッドもつかって行全体を選択状態にできるようにしておきます。
そのあとUndoBufに必要な情報を格納して「中央揃え」「左揃え」「右揃え」をおこないます。
まず現在の状態と変更後の状態を保存するクラスです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public partial class SyncRichTextBox : UserControl { internal class TextAlignInfo { internal TextAlignInfo(int charIndex, HorizontalAlignment oldTextAlign, HorizontalAlignment newTextAlign) { CharIndex = charIndex; OldTextAlign = oldTextAlign; NewTextAlign = newTextAlign; } internal int CharIndex { get; } = 0; internal HorizontalAlignment NewTextAlign { get; } = HorizontalAlignment.Left; internal HorizontalAlignment OldTextAlign { get; } = HorizontalAlignment.Left; } } |
HorizontalAlignmentを引数にしたメソッドです。
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 |
public partial class SyncRichTextBox : UserControl { void ChangeTextAlign(HorizontalAlignment newTextAlign) { 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<TextAlignInfo> textAlignInfos = new List<TextAlignInfo>(); foreach (int index in vs) { richTextBoxEx1.Select(index, 0); textAlignInfos.Add(new TextAlignInfo(index, richTextBoxEx1.SelectionAlignment, newTextAlign)); } if (!textAlignInfos.Any(x => x.OldTextAlign != newTextAlign)) return; buf.TextAlignInfos = textAlignInfos; if (newTextAlign == HorizontalAlignment.Left) buf.action = "TextAlignLeft"; if (newTextAlign == HorizontalAlignment.Right) buf.action = "TextAlignRight"; if (newTextAlign == HorizontalAlignment.Center) buf.action = "TextAlignCenter"; if (ChangeTextAlign(buf)) Data.InsertUndobuf(buf); } bool ChangeTextAlign(Undobuf buf) { foreach (var rich in Data.SyncRichTextBoxes) { rich.Data.GetRichTextBoxInfo(rich).SelectionStart = rich.SelectionStart; } OnTextChanging(buf); if (buf.IsCancel) return false; foreach (var rich in Data.SyncRichTextBoxes) { var info = rich.Data.GetRichTextBoxInfo(rich); int oldStart = info.SelectionStart; foreach (TextAlignInfo info1 in buf.TextAlignInfos) { if (rich.Data == Data) { rich.richTextBoxEx1.Select(info1.CharIndex, 0); rich.richTextBoxEx1.SelectionAlignment = info1.NewTextAlign; } } 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; } } |
変更前と変更後で違いがない場合はなにもしないようにしています。
UndoできるようにUndobufにデータを格納できるようにします。UndoのときはNewTextAlignとOldTextAlignが逆になるのでそのような処理ができるようにしています。
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 |
public class Undobuf { List<TextAlignInfo> _textAlignInfos = null; internal List<TextAlignInfo> TextAlignInfos { set { _textAlignInfos = value; } get { if (_textAlignInfos == null) return null; List<TextAlignInfo> ret = new List<TextAlignInfo>(); if (IsUndo) { foreach (var info in _textAlignInfos) { TextAlignInfo info1 = new TextAlignInfo(info.CharIndex, info.NewTextAlign, info.OldTextAlign); ret.Add(info1); } } else { foreach (var info in _textAlignInfos) { ret.Add(info); } } return ret; } } } public partial class SyncRichTextBox : UserControl { public void Undo() { var buf = Data.GetUndobuf(); if (buf == null) return; buf.IsUndo = true; // その他の処理省略 if (buf.TextAlignInfos != null) ChangeTextAlign(buf); buf.IsUndo = false; Data.MoveToRedobufs(); } public void Redo() { var buf = Data.GetRedobuf(); if (buf == null) return; // その他の処理省略 if (buf.TextAlignInfos != null) ChangeTextAlign(buf); Data.MoveToUndobufs(); } } |
あとは
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public partial class SyncRichTextBox : UserControl { public HorizontalAlignment SelectionAlignment { set { if (value == HorizontalAlignment.Left) { ChangeTextAlign(HorizontalAlignment.Left); } if (value == HorizontalAlignment.Right) { ChangeTextAlign(HorizontalAlignment.Right); } if (value == HorizontalAlignment.Center) { ChangeTextAlign(HorizontalAlignment.Center); } } } } |
これで同期されたRichTextBoxで「中央揃え」「左揃え」「右揃え」ができるようになります。