/// <summary> /// カーソル位置とテキストをUndo/Redoに保持する /// </summary> /// <param name="previous"></param> /// <param name="target"></param> private void SaveCursorAndTextOnTextBox(ref CursorAndText previous, TextBox target, Func <CursorAndText, bool> breakCondition = null) { BaseUndoRedoManager manager; lock (_SyncObjForm) { manager = _TextBoxToManager[target]; } CursorAndText _previous; CursorAndText current; lock (_SyncObjForm) { _previous = new CursorAndText() { CursorPosition = previous.CursorPosition, Text = previous.Text }; current = new CursorAndText() { CursorPosition = target.SelectionStart, Text = target.Text }; //旧情報の書き換え previous = current; if (breakCondition != null) { if (breakCondition(_previous)) { return; } } } manager.Do(new Command( () =>//Doした場合(=今)の処理 { }, () =>//Undoした場合の処理 { lock (_SyncObjForm) { target.Text = _previous.Text; target.SelectionStart = _previous.CursorPosition; } }, () =>//Redoした場合の処理 { lock (_SyncObjForm) { target.Text = current.Text; target.SelectionStart = current.CursorPosition; } })); }
public FormMain() { InitializeComponent(); _DefaultCursor = Cursor.Current; _Rule = new RuleGrass(); _PreviousCursorAndTextSourceCode = new CursorAndText() { CursorPosition = 0, Text = string.Empty }; _PreviousCursorAndTextVisualized = new CursorAndText() { CursorPosition = 0, Text = string.Empty }; _SourceManager = new FixedSizeUndoRedoManager(100); _VisualizedManager = new FixedSizeUndoRedoManager(100); _TextBoxToManager = new Dictionary <TextBox, BaseUndoRedoManager>(); _TextBoxToManager[textBoxSourceCode] = _SourceManager; _TextBoxToManager[textBoxVisualizedLanguage] = _VisualizedManager; _SettingTextChangedFromSystem = new Dictionary <TextBox, Action <bool> >(); _SettingTextChangedFromSystem[textBoxSourceCode] = (value) => _IsSourceCodeChangedFromSystem = value; _SettingTextChangedFromSystem[textBoxVisualizedLanguage] = (value) => _IsVisualizedLanguageChangedFromSystem = value; _GettingTextChangedFromSystem = new Dictionary <TextBox, Func <bool> >(); _GettingTextChangedFromSystem[textBoxSourceCode] = () => _IsSourceCodeChangedFromSystem; _GettingTextChangedFromSystem[textBoxVisualizedLanguage] = () => _IsVisualizedLanguageChangedFromSystem; //Ctrl+Tabでソースコード<=>可視化言語を変換する textBoxSourceCode.AddKeyPressEvent( (Keys.Control | Keys.Tab), () => { GllSourceToVisualized(); } ); textBoxVisualizedLanguage.AddKeyPressEvent( (Keys.Control | Keys.Tab), () => { VisualizedToGllSource(); } ); //タイマーでUndo記録を管理 _TimerSaveSourceState = new Timer(); _TimerSaveSourceState.Interval = _TimerInterval; _TimerSaveSourceState.Tick += (sender, e) => { var breakCondition = new Func <CursorAndText, bool>( (pre) => pre.Text == textBoxSourceCode.Text || _GettingTextChangedFromSystem[textBoxSourceCode]()); lock (_SyncObjForm) { //Undo,Redoの挙動を記録 SaveCursorAndTextOnTextBox(ref _PreviousCursorAndTextSourceCode, textBoxSourceCode, breakCondition); } }; _TimerSaveVisualizedState = new Timer(); _TimerSaveVisualizedState.Interval = _TimerInterval; _TimerSaveVisualizedState.Tick += (sender, e) => { var breakCondition = new Func <CursorAndText, bool>( (pre) => pre.Text == textBoxVisualizedLanguage.Text || _GettingTextChangedFromSystem[textBoxVisualizedLanguage]()); lock (_SyncObjForm) { //Undo,Redoの挙動を記録 SaveCursorAndTextOnTextBox(ref _PreviousCursorAndTextVisualized, textBoxVisualizedLanguage, breakCondition); } }; _TimerSaveSourceState.Start(); _TimerSaveVisualizedState.Start(); }