Primary WPF APIs:
RoutedCommand, RoutedUICommandCommandBindingCommandManager.RequerySuggested / InvalidateRequerySuggested()Primary Avalonia APIs:
ICommand command sources (Button, MenuItem, ToggleButton)KeyBinding and HotKey for keyboard activationCanExecuteChangedAvalonia 11.3.12 does not provide WPF CommandManager/CommandBinding routing primitives.
| WPF | Avalonia |
|---|---|
RoutedCommand + CommandBinding |
ICommand on control + view-model command handlers |
CommandManager.RequerySuggested |
explicit CanExecuteChanged raise from command implementation |
Window.InputBindings |
KeyBindings on Window/UserControl |
WPF XAML:
<Window.CommandBindings>
<CommandBinding Command="{x:Static ApplicationCommands.Save}"
Executed="SaveExecuted"
CanExecute="SaveCanExecute" />
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Command="{x:Static ApplicationCommands.Save}" Gesture="Ctrl+S" />
</Window.InputBindings>
Avalonia XAML:
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:MyApp.ViewModels"
x:DataType="vm:EditorViewModel">
<UserControl.KeyBindings>
<KeyBinding Gesture="Ctrl+S" Command="{CompiledBinding SaveCommand}" />
</UserControl.KeyBindings>
<StackPanel Spacing="8">
<Button Content="Save"
Command="{CompiledBinding SaveCommand}" />
<TextBlock Text="{CompiledBinding SaveStatus}" />
</StackPanel>
</UserControl>
using System;
using System.Windows.Input;
using Avalonia.Controls;
using Avalonia.Input;
public sealed class RelayCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public RelayCommand(Action execute, Func<bool> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public event EventHandler? CanExecuteChanged;
public bool CanExecute(object? parameter) => _canExecute();
public void Execute(object? parameter) => _execute();
public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
var saveCommand = new RelayCommand(
execute: () => viewModel.Save(),
canExecute: () => viewModel.CanSave);
var root = new UserControl();
root.KeyBindings.Add(new KeyBinding
{
Gesture = KeyGesture.Parse("Ctrl+S"),
Command = saveCommand
});
// Replace CommandManager.InvalidateRequerySuggested():
viewModel.CanSave = false;
saveCommand.RaiseCanExecuteChanged();
CanExecute does not refresh automatically after state changes.
CanExecuteChanged explicitly when relevant state changes.KeyBinding/HotKey; gesture text alone is only visual metadata.