using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Threading;
using Avalonia.VisualTree;
namespace Avalonia.Xaml.Interactions.Custom;
///
///
///
public class ButtonExecuteCommandOnKeyDownBehavior : ExecuteCommandOnKeyBehaviorBase
{
///
///
///
///
protected override void OnAttachedToVisualTree(CompositeDisposable disposables)
{
if (AssociatedObject?.GetVisualRoot() is InputElement inputRoot)
{
var disposable = inputRoot.AddDisposableHandler(InputElement.KeyDownEvent, RootDefaultKeyDown);
disposables.Add(disposable);
}
}
private void RootDefaultKeyDown(object? sender, KeyEventArgs e)
{
var haveKey = Key is not null && e.Key == Key;
var haveGesture = Gesture is not null && Gesture.Matches(e);
if (!haveKey && !haveGesture)
{
return;
}
if (AssociatedObject is Button button)
{
ExecuteCommand(button);
}
}
private bool ExecuteCommand(Button button)
{
if (!IsEnabled)
{
return false;
}
if (button is not { IsVisible: true, IsEnabled: true })
{
return false;
}
if (button.Command?.CanExecute(button.CommandParameter) != true)
{
return false;
}
if (FocusTopLevel)
{
Dispatcher.UIThread.Post(() => (AssociatedObject?.GetVisualRoot() as TopLevel)?.Focus());
}
if (FocusControl is { } focusControl)
{
Dispatcher.UIThread.Post(() => focusControl.Focus());
}
button.Command.Execute(button.CommandParameter);
return true;
}
}