1
0
Эх сурвалжийг харах

Moved the reentrancy check to TextBox.

Steven Kirk 7 жил өмнө
parent
commit
6682c3e2dc

+ 20 - 3
src/Avalonia.Controls/TextBox.cs

@@ -85,6 +85,7 @@ namespace Avalonia.Controls
         private int _selectionEnd;
         private TextPresenter _presenter;
         private UndoRedoHelper<UndoRedoState> _undoRedoHelper;
+        private bool _isUndoingRedoing;
         private bool _ignoreTextChanges;
         private static readonly string[] invalidCharacters = new String[1]{"\u007f"};
 
@@ -199,7 +200,7 @@ namespace Avalonia.Controls
                 {
                     CaretIndex = CoerceCaretIndex(CaretIndex, value?.Length ?? 0);
 
-                    if (SetAndRaise(TextProperty, ref _text, value))
+                    if (SetAndRaise(TextProperty, ref _text, value) && !_isUndoingRedoing)
                     {
                         _undoRedoHelper.Clear();
                     }
@@ -368,14 +369,30 @@ namespace Avalonia.Controls
                 case Key.Z:
                     if (modifiers == InputModifiers.Control)
                     {
-                        _undoRedoHelper.Undo();
+                        try
+                        {
+                            _isUndoingRedoing = true;
+                            _undoRedoHelper.Undo();
+                        }
+                        finally
+                        {
+                            _isUndoingRedoing = false;
+                        }
                         handled = true;
                     }
                     break;
                 case Key.Y:
                     if (modifiers == InputModifiers.Control)
                     {
-                        _undoRedoHelper.Redo();
+                        try
+                        {
+                            _isUndoingRedoing = true;
+                            _undoRedoHelper.Redo();
+                        }
+                        finally
+                        {
+                            _isUndoingRedoing = false;
+                        }
                         handled = true;
                     }
                     break;

+ 7 - 26
src/Avalonia.Controls/Utils/UndoRedoHelper.cs

@@ -10,7 +10,6 @@ namespace Avalonia.Controls.Utils
     class UndoRedoHelper<TState> : WeakTimer.IWeakTimerSubscriber where TState : struct, IEquatable<TState>
     {
         private readonly IUndoRedoHost _host;
-        bool _undoRedoing;
 
         public interface IUndoRedoHost
         {
@@ -33,19 +32,10 @@ namespace Avalonia.Controls.Utils
 
         public void Undo()
         {
-            _undoRedoing = true;
-
-            try
-            {
-                if (_currentNode?.Previous != null)
-                {
-                    _currentNode = _currentNode.Previous;
-                    _host.UndoRedoState = _currentNode.Value;
-                }
-            }
-            finally
+            if (_currentNode?.Previous != null)
             {
-                _undoRedoing = false;
+                _currentNode = _currentNode.Previous;
+                _host.UndoRedoState = _currentNode.Value;
             }
         }
 
@@ -80,19 +70,10 @@ namespace Avalonia.Controls.Utils
 
         public void Redo()
         {
-            _undoRedoing = true;
-
-            try
-            {
-                if (_currentNode?.Next != null)
-                {
-                    _currentNode = _currentNode.Next;
-                    _host.UndoRedoState = _currentNode.Value;
-                }
-            }
-            finally
+            if (_currentNode?.Next != null)
             {
-                _undoRedoing = false;
+                _currentNode = _currentNode.Next;
+                _host.UndoRedoState = _currentNode.Value;
             }
         }
 
@@ -112,7 +93,7 @@ namespace Avalonia.Controls.Utils
 
         public void Clear()
         {
-            if (!_undoRedoing) _states.Clear();
+            _states.Clear();
         }
 
         bool WeakTimer.IWeakTimerSubscriber.Tick()