diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs
index 76bb37efcf..eb9f82516e 100644
--- a/src/Avalonia.Controls/TextBox.cs
+++ b/src/Avalonia.Controls/TextBox.cs
@@ -160,22 +160,41 @@ namespace Avalonia.Controls
(o, v) => o.UndoLimit = v,
unsetValue: -1);
+ ///
+ /// Defines the event.
+ ///
public static readonly RoutedEvent CopyingToClipboardEvent =
RoutedEvent.Register(
nameof(CopyingToClipboard), RoutingStrategies.Bubble);
+ ///
+ /// Defines the event.
+ ///
public static readonly RoutedEvent CuttingToClipboardEvent =
RoutedEvent.Register(
nameof(CuttingToClipboard), RoutingStrategies.Bubble);
+ ///
+ /// Defines the event.
+ ///
public static readonly RoutedEvent PastingFromClipboardEvent =
RoutedEvent.Register(
nameof(PastingFromClipboard), RoutingStrategies.Bubble);
+ ///
+ /// Defines the event.
+ ///
public static readonly RoutedEvent TextChangedEvent =
RoutedEvent.Register(
nameof(TextChanged), RoutingStrategies.Bubble);
+ ///
+ /// Defines the event.
+ ///
+ public static readonly RoutedEvent TextChangingEvent =
+ RoutedEvent.Register(
+ nameof(TextChanging), RoutingStrategies.Bubble);
+
readonly struct UndoRedoState : IEquatable
{
public string? Text { get; }
@@ -570,17 +589,26 @@ namespace Avalonia.Controls
}
///
- /// Occurs when text changes.
+ /// Occurs asynchronously after text changes and the new text is rendered.
///
- ///
- /// This event is asynchronous and occurs after the new text is rendered.
- ///
public event EventHandler? TextChanged
{
add => AddHandler(TextChangedEvent, value);
remove => RemoveHandler(TextChangedEvent, value);
}
+ ///
+ /// Occurs synchronously when text starts to change but before it is rendered.
+ ///
+ ///
+ /// This event occurs just after the property value has been updated.
+ ///
+ public event EventHandler? TextChanging
+ {
+ add => AddHandler(TextChangingEvent, value);
+ remove => RemoveHandler(TextChangingEvent, value);
+ }
+
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
_presenter = e.NameScope.Get("PART_TextPresenter");
@@ -1564,11 +1592,19 @@ namespace Avalonia.Controls
if (textChanged)
{
+ // Note the following sequence of these events (following WinUI)
+ // 1. TextChanging occurs synchronously when text starts to change but before it is rendered.
+ // This occurs after the Text property is set.
+ // 2. TextChanged occurs asynchronously after text changes and the new text is rendered.
+
+ var textChangingEventArgs = new RoutedEventArgs(TextChangingEvent);
+ RaiseEvent(textChangingEventArgs);
+
Dispatcher.UIThread.Post(() =>
{
- var eventArgs = new RoutedEventArgs(TextChangedEvent);
- RaiseEvent(eventArgs);
- });
+ var textChangedEventArgs = new RoutedEventArgs(TextChangedEvent);
+ RaiseEvent(textChangedEventArgs);
+ }, DispatcherPriority.Normal);
}
}
else