Browse Source

Merge pull request #1955 from donandren/issues/1954

Fixed TextBox OutOfRangeException
Steven Kirk 7 years ago
parent
commit
db9678041e

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

@@ -212,7 +212,10 @@ namespace Avalonia.Controls
             {
                 if (!_ignoreTextChanges)
                 {
-                    CaretIndex = CoerceCaretIndex(CaretIndex, value?.Length ?? 0);
+                    var caretIndex = CaretIndex;
+                    SelectionStart = CoerceCaretIndex(SelectionStart, value?.Length ?? 0);
+                    SelectionEnd = CoerceCaretIndex(SelectionEnd, value?.Length ?? 0);
+                    CaretIndex = CoerceCaretIndex(caretIndex, value?.Length ?? 0);
 
                     if (SetAndRaise(TextProperty, ref _text, value) && !_isUndoingRedoing)
                     {

+ 74 - 1
tests/Avalonia.Controls.UnitTests/TextBoxTests.cs

@@ -8,7 +8,6 @@ using Avalonia.Controls.Primitives;
 using Avalonia.Controls.Templates;
 using Avalonia.Data;
 using Avalonia.Input;
-using Avalonia.Markup.Data;
 using Avalonia.Media;
 using Avalonia.Platform;
 using Avalonia.UnitTests;
@@ -322,6 +321,71 @@ namespace Avalonia.Controls.UnitTests
             }
         }
 
+        [Fact]
+        public void SelectionEnd_Doesnt_Cause_Exception()
+        {
+            using (UnitTestApplication.Start(Services))
+            {
+                var target = new TextBox
+                {
+                    Template = CreateTemplate(),
+                    Text = "0123456789"
+                };
+
+                target.SelectionStart = 0;
+                target.SelectionEnd = 9;
+
+                target.Text = "123";
+
+                RaiseTextEvent(target, "456");
+
+                Assert.True(true);
+            }
+        }
+
+        [Fact]
+        public void SelectionStart_Doesnt_Cause_Exception()
+        {
+            using (UnitTestApplication.Start(Services))
+            {
+                var target = new TextBox
+                {
+                    Template = CreateTemplate(),
+                    Text = "0123456789"
+                };
+
+                target.SelectionStart = 8;
+                target.SelectionEnd = 9;
+
+                target.Text = "123";
+
+                RaiseTextEvent(target, "456");
+
+                Assert.True(true);
+            }
+        }
+
+        [Fact]
+        public void SelectionStartEnd_Are_Valid_AterTextChange()
+        {
+            using (UnitTestApplication.Start(Services))
+            {
+                var target = new TextBox
+                {
+                    Template = CreateTemplate(),
+                    Text = "0123456789"
+                };
+
+                target.SelectionStart = 8;
+                target.SelectionEnd = 9;
+
+                target.Text = "123";
+
+                Assert.True(target.SelectionStart <= "123".Length);
+                Assert.True(target.SelectionEnd <= "123".Length);
+            }
+        }
+
         private static TestServices Services => TestServices.MockThreadingInterface.With(
             standardCursorFactory: Mock.Of<IStandardCursorFactory>());
 
@@ -351,6 +415,15 @@ namespace Avalonia.Controls.UnitTests
             });
         }
 
+        private void RaiseTextEvent(TextBox textBox, string text)
+        {
+            textBox.RaiseEvent(new TextInputEventArgs
+            {
+                RoutedEvent = InputElement.TextInputEvent,
+                Text = text
+            });
+        }
+
         private class Class1 : NotifyingBase
         {
             private int _foo;