ButtonExecuteCommandOnKeyDownBehavior.cs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. using System.Reactive.Disposables;
  2. using Avalonia.Controls;
  3. using Avalonia.Input;
  4. using Avalonia.Interactivity;
  5. using Avalonia.Threading;
  6. using Avalonia.VisualTree;
  7. namespace Avalonia.Xaml.Interactions.Custom;
  8. /// <summary>
  9. ///
  10. /// </summary>
  11. public class ButtonExecuteCommandOnKeyDownBehavior : ExecuteCommandOnKeyBehaviorBase
  12. {
  13. /// <summary>
  14. ///
  15. /// </summary>
  16. /// <param name="disposables"></param>
  17. protected override void OnAttachedToVisualTree(CompositeDisposable disposables)
  18. {
  19. if (AssociatedObject?.GetVisualRoot() is InputElement inputRoot)
  20. {
  21. var disposable = inputRoot.AddDisposableHandler(InputElement.KeyDownEvent, RootDefaultKeyDown);
  22. disposables.Add(disposable);
  23. }
  24. }
  25. private void RootDefaultKeyDown(object? sender, KeyEventArgs e)
  26. {
  27. var haveKey = Key is not null && e.Key == Key;
  28. var haveGesture = Gesture is not null && Gesture.Matches(e);
  29. if (!haveKey && !haveGesture)
  30. {
  31. return;
  32. }
  33. if (AssociatedObject is Button button)
  34. {
  35. ExecuteCommand(button);
  36. }
  37. }
  38. private bool ExecuteCommand(Button button)
  39. {
  40. if (!IsEnabled)
  41. {
  42. return false;
  43. }
  44. if (button is not { IsVisible: true, IsEnabled: true })
  45. {
  46. return false;
  47. }
  48. if (button.Command?.CanExecute(button.CommandParameter) != true)
  49. {
  50. return false;
  51. }
  52. if (FocusTopLevel)
  53. {
  54. Dispatcher.UIThread.Post(() => (AssociatedObject?.GetVisualRoot() as TopLevel)?.Focus());
  55. }
  56. if (FocusControl is { } focusControl)
  57. {
  58. Dispatcher.UIThread.Post(() => focusControl.Focus());
  59. }
  60. button.Command.Execute(button.CommandParameter);
  61. return true;
  62. }
  63. }