diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs
index 6838f27262..fc94c6e908 100644
--- a/src/Avalonia.Controls/TextBox.cs
+++ b/src/Avalonia.Controls/TextBox.cs
@@ -396,6 +396,14 @@ namespace Avalonia.Controls
get { return _newLine; }
set { SetAndRaise(NewLineProperty, ref _newLine, value); }
}
+
+ ///
+ /// Clears the current selection, maintaining the
+ ///
+ public void ClearSelection()
+ {
+ SelectionStart = SelectionEnd = CaretIndex;
+ }
///
/// Property for determining if the Cut command can be executed.
@@ -479,8 +487,7 @@ namespace Avalonia.Controls
if (ContextMenu == null || !ContextMenu.IsOpen)
{
- SelectionStart = 0;
- SelectionEnd = 0;
+ ClearSelection();
RevealPassword = false;
}
@@ -512,7 +519,7 @@ namespace Avalonia.Controls
text = Text ?? string.Empty;
SetTextInternal(text.Substring(0, caretIndex) + input + text.Substring(caretIndex));
CaretIndex += input.Length;
- SelectionStart = SelectionEnd = CaretIndex;
+ ClearSelection();
_undoRedoHelper.DiscardRedo();
}
}
@@ -737,7 +744,7 @@ namespace Avalonia.Controls
SetTextInternal(text.Substring(0, caretIndex - removedCharacters) +
text.Substring(caretIndex));
CaretIndex -= removedCharacters;
- SelectionStart = SelectionEnd = CaretIndex;
+ ClearSelection();
}
_undoRedoHelper.Snapshot();
@@ -810,7 +817,7 @@ namespace Avalonia.Controls
}
else if (movement)
{
- SelectionStart = SelectionEnd = CaretIndex;
+ ClearSelection();
}
if (handled || movement)
@@ -1117,7 +1124,8 @@ namespace Avalonia.Controls
var end = Math.Max(selectionStart, selectionEnd);
var text = Text;
SetTextInternal(text.Substring(0, start) + text.Substring(end));
- SelectionStart = SelectionEnd = CaretIndex = start;
+ CaretIndex = start;
+ ClearSelection();
return true;
}
else
@@ -1206,7 +1214,8 @@ namespace Avalonia.Controls
set
{
Text = value.Text;
- SelectionStart = SelectionEnd = CaretIndex = value.CaretPosition;
+ CaretIndex = value.CaretPosition;
+ ClearSelection();
}
}
}
diff --git a/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs b/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs
index f41938a9bb..fe25fa7346 100644
--- a/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs
@@ -562,6 +562,41 @@ namespace Avalonia.Controls.UnitTests
}
}
+ [Fact]
+ public void TextBox_CaretIndex_Persists_When_Focus_Lost()
+ {
+ using (UnitTestApplication.Start(FocusServices))
+ {
+ var target1 = new TextBox
+ {
+ Template = CreateTemplate(),
+ Text = "1234"
+ };
+ var target2 = new TextBox
+ {
+ Template = CreateTemplate(),
+ Text = "5678"
+ };
+ var sp = new StackPanel();
+ sp.Children.Add(target1);
+ sp.Children.Add(target2);
+
+ target1.ApplyTemplate();
+ target2.ApplyTemplate();
+
+ var root = new TestRoot { Child = sp };
+
+ target2.Focus();
+ target2.CaretIndex = 2;
+ Assert.False(target1.IsFocused);
+ Assert.True(target2.IsFocused);
+
+ target1.Focus();
+
+ Assert.Equal(2, target2.CaretIndex);
+ }
+ }
+
[Fact]
public void TextBox_Reveal_Password_Reset_When_Lost_Focus()
{