序章
WPF (Windows Presentation Foundation) は、Windows アプリケーションを構築するための Microsoft UI フレームワークです。WPF では、Command を使用して操作のバインドを実現したり、Command を使用して操作を UI インターフェイスから分離したりできるため、コードがより明確で理解しやすくなります。この記事では、WPF のコマンドについて、各コマンドの実装を含めて詳しく紹介し、具体的な例を示します。
ルーテッドコマンド
RoutedCommand は WPF のコマンドであり、コマンドを UI インターフェイスから分離し、異なる UI 要素間で共有できます。RoutedCommand は、CommandBinding を通じて UI 要素にバインドする必要があります。次のコードを使用して RoutedCommand を作成できます。
public static readonly RoutedCommand MyCommand = new RoutedCommand();
次に、次のコードを使用して、RoutedCommand を UI 要素にバインドできます。
<MenuItem Command="{x:Static local:MainWindow.MyCommand}" />
次のように、コマンドを処理するためにコードに CommandBinding を実装する必要もあります。
CommandBinding binding = new CommandBinding(MyCommand, MyCommand_Executed, MyCommand_CanExecute);
this.CommandBindings.Add(binding);
このうち、MyCommand_Executed と MyCommand_CanExecute はコマンドを処理するためのメソッドであり、これら 2 つのメソッドには特定のコマンド ロジックを実装する必要があります。
リレーコマンド
RelayCommand は、コマンドを UI インターフェイスから分離し、ViewModel のメソッドにバインドする軽量のコマンド実装です。次のコードを使用して RelayCommand を作成できます。
public class RelayCommand : ICommand
{
private Action<object> _execute;
private Func<object, bool> _canExecute;
public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException("execute");
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
次に、次のように ViewModel で RelayCommand のインスタンスを作成できます。
public class ViewModel
{
public ICommand MyCommand { get; private set; }
public ViewModel()
{
MyCommand = new RelayCommand(ExecuteMyCommand, CanExecuteMyCommand);
}
private bool CanExecuteMyCommand(object parameter)
{
// Add logic to determine if command can execute
return true;
}
private void ExecuteMyCommand(object parameter)
{
// Add logic to execute command
}
}
最後に、次のように XAML で RelayCommand をバインドできます。
<Button Command="{Binding MyCommand}" />
デリゲートコマンド
DelegateCommand はコマンドを実装するもう 1 つの方法で、コマンドを UI インターフェイスから分離し、ViewModel のメソッドにバインドできます。DelegateCommand と RelayCommand の実装は似ており、次のコードを使用して DelegateCommand を作成できます。
public class DelegateCommand : ICommand
{
private Action<object> _execute;
private Func<object, bool> _canExecute;
public DelegateCommand(Action<object> execute, Func<object, bool> canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException("execute");
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
次に、次のように ViewModel で DelegateCommand のインスタンスを作成できます。
public class ViewModel
{
public ICommand MyCommand { get; private set; }
public ViewModel()
{
MyCommand = new DelegateCommand(ExecuteMyCommand, CanExecuteMyCommand);
}
private bool CanExecuteMyCommand(object parameter)
{
// Add logic to determine if command can execute
return true;
}
private void ExecuteMyCommand(object parameter)
{
// Add logic to execute command
}
}
最後に、次のように XAML で DelegateCommand をバインドできます。
<Button Command="{Binding MyCommand}" />
上記の 3 つのコマンド実装メソッドに加えて、ICommand インターフェイスのカスタム実装、EventToCommand、InvokeCommandAction など、その他の一般的に使用されるコマンド実装メソッドもあります。これらのコマンド実装方法にはそれぞれ長所と短所があり、実際のニーズに応じて適切な方法を選択する必要があります。コマンドを使用する場合は、コードの可読性や保守性に影響を与える過度の使用や複雑すぎるコマンド チェーンを避けるように注意する必要があります。この記事が WPF のコマンドについての理解をさらに深めてくれることを願っています。
上記の紹介から、WPF でのコマンドの使用は非常に柔軟であり、実際のニーズに応じてさまざまなコマンド実装方法を選択できることがわかります。コマンドを使用すると、操作を UI インターフェイスから分離できるため、コードがより明確で理解しやすくなります。コマンドを使用する場合は、コードの可読性や保守性に影響を与える過度の使用や複雑すぎるコマンド チェーンを避けるように注意する必要があります。この記事が皆さんのお役に立てれば幸いです。