DelegateCommandは、ViewModelのメソッドを呼び出すためのICommand実装クラスです。
DelegateCommandを利用することで、メソッドごとにICommandインターフェースを持ったクラスを用意する手間を省くことができます。
public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod);
コンストラクタでDelegateCommandインスタンスを生成します。
using Prism.Commands; using Prism.Mvvm; namespace WpfPrismMvvm { public class MainWindowViewModel : BindableBase { private string _bindtext; public string BindText { get { return _bindtext; } set { SetProperty(ref _bindtext, value); } } public DelegateCommand ButtonClickedCommand { get; private set; } public MainWindowViewModel() { ButtonClickedCommand = new DelegateCommand( () => { BindText += "The button is Clicked!\r\n"; }, // 実行処理 () => true); // 実行可否:trueなので実行可能 } } }
ボタンにコマンドを割り当てます。
<Window x:Class="WpfPrismMvvm.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="MainWindow" Height="320" Width="480"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="2*"/> <RowDefinition Height="1*"/> </Grid.RowDefinitions> <TextBox Text="{Binding BindText, UpdateSourceTrigger=PropertyChanged}" x:Name="EditBox" Margin="10" TextWrapping="Wrap" IsReadOnly="True" Grid.Row="0"/> <Button Command="{Binding ButtonClickedCommand}" Content="Execute DelegateCommand" Grid.Row="1" /> </Grid> </Window>
DelegateCommandを利用することで、以降UI変更(コマンドが追加されること)があっても、コードビハインドは変更する必要がありません。
using System.Windows; namespace WpfPrismMvvm { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); MainWindowViewModel vm = new MainWindowViewModel(); this.DataContext = vm; } } }
canExecuteMethodのbool値により、コンポーネントがDisableになります。
ButtonClickedCommand = new DelegateCommand( () => { BindText += "The button is Clicked!\r\n"; }, () => false);
アプリケーション実行中はボタンDisable化するようなcanExecuteMethodの動的切り替えを行う場合はObservesPropertyを利用します。
using Prism.Commands; using Prism.Mvvm; using System.Threading.Tasks; namespace WpfPrismMvvm { public class MainWindowViewModel : BindableBase { private string _readtext; public string ReadText { get { return _readtext; } set { SetProperty(ref _readtext, value); } } private string _inputText; public string InputText { get { return _inputText; } set { SetProperty(ref _inputText, value); } } public DelegateCommand ButtonClickedCommand { get; private set; } public MainWindowViewModel() { ButtonClickedCommand = new DelegateCommand( ButtonClickedProcess, CanExecuteButtonClickedCommand).ObservesProperty(() => InputText); } /// <summary> /// ボタンを実行できるか判定する処理。 /// </summary> /// <returns></returns> private bool CanExecuteButtonClickedCommand() { return !string.IsNullOrWhiteSpace(InputText); } /// <summary> /// ボタン押下時の処理 /// </summary> private void ButtonClickedProcess() { ReadText += InputText; InputText = string.Empty; } } }
(備考)xaml
<Window x:Class="WpfPrismMvvm.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="MainWindow" Height="320" Width="480"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="2*"/> <RowDefinition Height="1*"/> </Grid.RowDefinitions> <TextBox Text="{Binding ReadText, UpdateSourceTrigger=PropertyChanged}" x:Name="EditBox" Margin="10" TextWrapping="Wrap" IsReadOnly="True" Grid.Row="0"/> <StackPanel Grid.Row="1" Orientation="Horizontal"> <TextBox Text="{Binding InputText, UpdateSourceTrigger=PropertyChanged}" Margin="10" MinWidth="260"/> <Button Command="{Binding ButtonClickedCommand}" Content="Execute DelegateCommand" Margin="10" MinWidth="150" /> </StackPanel> </Grid> </Window>