UI とビジネスロジックの分離が鍵となる MVVM(Model-View-ViewModel)デザインパターンに、コマンドは必要不可欠です。Toolbar for WPF はコマンドフレームワークをサポートしており、一般的な MVVM パターンと組み合わせて使用できます。MVVM 設計のアプリケーションでは、コマンドターゲットが ViewModel で実装されることがよくありますが、これらは UI 要素ツリーに含まれません。したがって、MVVM で ICommand を使用する方法として RoutedCommand は最適な実装ではありません。DelegateCommand、RelayCommand などの特別な実装を使用する必要があります。これらは、View が UI 要素ツリーに含まれないオブジェクトに連結できるようにします。
以下の手順は、RelayCommand クラスと C1Toolbar を使用して、2部で実装したカスタムコマンドと同じカスタムコマンドを作成する方法を示します。
INotifyPropertyChanged インターフェイスを実装する新しいクラス MainViewModel を作成します。このクラスは、C1Toolbar を含む View の ViewModel として機能します。
C# |
コードのコピー
|
---|---|
class MainViewModel : System.ComponentModel.INotifyPropertyChanged { private string textValue = ""; public string TextValue { get { return textValue; } set { textValue = value; OnPropertyChanged("TextValue"); } } private RelayCommand clearCommand; public ICommand ClearCommand { get { if (clearCommand == null) { clearCommand = new RelayCommand(param => this.Clear(), param => this.CanClear()); } return clearCommand; } } private bool CanClear() { return textValue.Length > 0; } private void Clear() { TextValue = ""; } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } } |
プロジェクトに RelayCommand クラスを追加します。
C# |
コードのコピー
|
---|---|
/// <summary> /// このクラスは、パラメータとして渡されるメソッドにコマンドロジックを委ねます。 /// また、View が、要素ツリーに含まれないオブジェクトにコマンドを連結できるようにします。 /// </summary> public class RelayCommand : ICommand { #region Fields readonly Action<object> _execute; readonly Predicate<object> _canExecute; #endregion // フィールド #region Constructors public RelayCommand(Action<object> execute) : this(execute, null) { } public RelayCommand(Action<object> execute, Predicate<object> canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } #endregion // コンストラクタ #region ICommand Members [DebuggerStepThrough] public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute(parameter); } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public void Execute(object parameter) { _execute(parameter); } #endregion // ICommand のメンバ } |
ViewModel に連結するには、C1Toolbar を含む View の先頭に次の XAML を追加します。
XAML |
コードのコピー
|
---|---|
<Window.Resources> <local:MainViewModel x:Key="viewModel" /> </Window.Resources> <Window.DataContext> <Binding Source="{StaticResource viewModel}"/> </Window.DataContext> |
続いて、1部で作成した C1Toolbar に次のツールバーグループを追加します。
XAML |
コードのコピー
|
---|---|
<c1:C1ToolbarGroup Header="アプリケーション"> <c1:C1ToolbarButton LabelTitle="テキストのクリア" Command="{Binding ClearCommand}" LargeImageSource="/Resources/delete.png"/> </c1:C1ToolbarGroup> |
このコマンドは MVVM のベストプラクティスに準拠する必要があります。したがって、TextBox にビジネスロジックを適用する場合は、TextBox の Text プロパティも ViewModel のある値に連結する必要があります。Text プロパティを ViewModel で定義されている TextValue プロパティに連結します。
XAML |
コードのコピー
|
---|---|
<TextBox Grid.Row="1" Text="{Binding TextValue, UpdateSourceTrigger=PropertyChanged}" Height="23" HorizontalAlignment="Left" Margin="12,17,0,0" Name="textBox1" VerticalAlignment="Top" Width="165" /> |
アプリケーションを実行し、カスタムな RelayCommand の動作を確認します。
MVVM 設計パターンに準拠すると、UI とビジネスロジックを緩く結合できるため、さまざまなメリットを得ることができます。