|
|
@@ -64,6 +64,12 @@ namespace Avalonia.Controls
|
|
|
public static readonly StyledProperty<bool> IsDefaultProperty =
|
|
|
AvaloniaProperty.Register<Button, bool>(nameof(IsDefault));
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Defines the <see cref="IsCancelProperty"/> property.
|
|
|
+ /// </summary>
|
|
|
+ public static readonly StyledProperty<bool> IsCancelProperty =
|
|
|
+ AvaloniaProperty.Register<Button, bool>(nameof(IsCancel));
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Defines the <see cref="Click"/> event.
|
|
|
/// </summary>
|
|
|
@@ -84,6 +90,7 @@ namespace Avalonia.Controls
|
|
|
FocusableProperty.OverrideDefaultValue(typeof(Button), true);
|
|
|
CommandProperty.Changed.Subscribe(CommandChanged);
|
|
|
IsDefaultProperty.Changed.Subscribe(IsDefaultChanged);
|
|
|
+ IsCancelProperty.Changed.Subscribe(IsCancelChanged);
|
|
|
PseudoClass<Button>(IsPressedProperty, ":pressed");
|
|
|
}
|
|
|
|
|
|
@@ -142,6 +149,16 @@ namespace Avalonia.Controls
|
|
|
set { SetValue(IsDefaultProperty, value); }
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Gets or sets a value indicating whether the button is the Cancel button for the
|
|
|
+ /// window.
|
|
|
+ /// </summary>
|
|
|
+ public bool IsCancel
|
|
|
+ {
|
|
|
+ get { return GetValue(IsCancelProperty); }
|
|
|
+ set { SetValue(IsCancelProperty, value); }
|
|
|
+ }
|
|
|
+
|
|
|
public bool IsPressed
|
|
|
{
|
|
|
get { return GetValue(IsPressedProperty); }
|
|
|
@@ -162,6 +179,13 @@ namespace Avalonia.Controls
|
|
|
ListenForDefault(inputElement);
|
|
|
}
|
|
|
}
|
|
|
+ if (IsCancel)
|
|
|
+ {
|
|
|
+ if (e.Root is IInputElement inputElement)
|
|
|
+ {
|
|
|
+ ListenForCancel(inputElement);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
@@ -351,6 +375,28 @@ namespace Avalonia.Controls
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Called when the <see cref="IsCancel"/> property changes.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="e">The event args.</param>
|
|
|
+ private static void IsCancelChanged(AvaloniaPropertyChangedEventArgs e)
|
|
|
+ {
|
|
|
+ var button = e.Sender as Button;
|
|
|
+ var isCancel = (bool)e.NewValue;
|
|
|
+
|
|
|
+ if (button?.VisualRoot is IInputElement inputRoot)
|
|
|
+ {
|
|
|
+ if (isCancel)
|
|
|
+ {
|
|
|
+ button.ListenForCancel(inputRoot);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ button.StopListeningForCancel(inputRoot);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Called when the <see cref="ICommand.CanExecuteChanged"/> event fires.
|
|
|
/// </summary>
|
|
|
@@ -373,7 +419,16 @@ namespace Avalonia.Controls
|
|
|
/// <param name="root">The input root.</param>
|
|
|
private void ListenForDefault(IInputElement root)
|
|
|
{
|
|
|
- root.AddHandler(KeyDownEvent, RootKeyDown);
|
|
|
+ root.AddHandler(KeyDownEvent, RootDefaultKeyDown);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Starts listening for the Enter key when the button <see cref="IsCancel"/>.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="root">The input root.</param>
|
|
|
+ private void ListenForCancel(IInputElement root)
|
|
|
+ {
|
|
|
+ root.AddHandler(KeyDownEvent, RootCancelKeyDown);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -382,7 +437,16 @@ namespace Avalonia.Controls
|
|
|
/// <param name="root">The input root.</param>
|
|
|
private void StopListeningForDefault(IInputElement root)
|
|
|
{
|
|
|
- root.RemoveHandler(KeyDownEvent, RootKeyDown);
|
|
|
+ root.RemoveHandler(KeyDownEvent, RootDefaultKeyDown);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Stops listening for the Escape key when the button is no longer <see cref="IsCancel"/>.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="root">The input root.</param>
|
|
|
+ private void StopListeningForCancel(IInputElement root)
|
|
|
+ {
|
|
|
+ root.RemoveHandler(KeyDownEvent, RootCancelKeyDown);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -390,12 +454,25 @@ namespace Avalonia.Controls
|
|
|
/// </summary>
|
|
|
/// <param name="sender">The event sender.</param>
|
|
|
/// <param name="e">The event args.</param>
|
|
|
- private void RootKeyDown(object sender, KeyEventArgs e)
|
|
|
+ private void RootDefaultKeyDown(object sender, KeyEventArgs e)
|
|
|
{
|
|
|
if (e.Key == Key.Enter && IsVisible && IsEnabled)
|
|
|
{
|
|
|
OnClick();
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Called when a key is pressed on the input root and the button <see cref="IsCancel"/>.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="sender">The event sender.</param>
|
|
|
+ /// <param name="e">The event args.</param>
|
|
|
+ private void RootCancelKeyDown(object sender, KeyEventArgs e)
|
|
|
+ {
|
|
|
+ if (e.Key == Key.Escape && IsVisible && IsEnabled)
|
|
|
+ {
|
|
|
+ OnClick();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|