Pārlūkot izejas kodu

Clear TextBox undo stack on binding change.

This makes `TextBox` act like WPF's `TextBox` where the undo/redo stack is cleared when a change is made from non-user input such as from a binding.

Fixes #336
Steven Kirk 7 gadi atpakaļ
vecāks
revīzija
f0afca5ead

+ 5 - 1
src/Avalonia.Controls/TextBox.cs

@@ -198,7 +198,11 @@ namespace Avalonia.Controls
                 if (!_ignoreTextChanges)
                 {
                     CaretIndex = CoerceCaretIndex(CaretIndex, value?.Length ?? 0);
-                    SetAndRaise(TextProperty, ref _text, value);
+
+                    if (SetAndRaise(TextProperty, ref _text, value))
+                    {
+                        _undoRedoHelper.Clear();
+                    }
                 }
             }
         }

+ 30 - 6
src/Avalonia.Controls/Utils/UndoRedoHelper.cs

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