Toolbar for WPF/Silverlight
3部:MVVM でのコマンドの使用
コマンドチュートリアル (WPF のみ) > 3部:MVVM でのコマンドの使用

UI とビジネスロジックの分離が鍵となる MVVM(Model-View-ViewModel)デザインパターンに、コマンドは必要不可欠です。Toolbar for WPF はコマンドフレームワークをサポートしており、一般的な MVVM パターンと組み合わせて使用できます。MVVM 設計のアプリケーションでは、コマンドターゲットが ViewModel で実装されることがよくありますが、これらは UI 要素ツリーに含まれません。したがって、MVVM で ICommand を使用する方法として RoutedCommand は最適な実装ではありません。DelegateCommandRelayCommand などの特別な実装を使用する必要があります。これらは、View が UI 要素ツリーに含まれないオブジェクトに連結できるようにします。

以下の手順は、RelayCommand クラスと C1Toolbar を使用して、2部で実装したカスタムコマンドと同じカスタムコマンドを作成する方法を示します。

  1. 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));
            }
        }
     
    }
    

    このクラスは、DelegateCommand の軽量バージョンである RelayCommand を使用します。どちらの ICommand 実装を使用しても、UI 要素ツリーには含まれないコマンドターゲットにパラメータとして渡されるメソッドに、コマンドロジックを委ねることができます。RelayCommand クラスと DelegateCommand クラスは、WPF フレームワークに含まれていません。これらは、オンラインまたはさまざまな MVVM ツールキットから入手できます。
  2. プロジェクトに 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 のメンバ
    }
    
  3. ViewModel に連結するには、C1Toolbar を含む View の先頭に次の XAML を追加します。

    XAML
    コードのコピー
    <Window.Resources>
    <local:MainViewModel x:Key="viewModel" />
    </Window.Resources>
    <Window.DataContext>
    <Binding Source="{StaticResource viewModel}"/>
    </Window.DataContext>
    

    これで、ViewModel がリソースとして追加され、Window または UserControl の DataContext に連結されます。
  4. 続いて、1部で作成した C1Toolbar に次のツールバーグループを追加します。

    XAML
    コードのコピー
    <c1:C1ToolbarGroup Header="アプリケーション">
        <c1:C1ToolbarButton LabelTitle="テキストのクリア" 
    
        Command="{Binding ClearCommand}" LargeImageSource="/Resources/delete.png"/>
    </c1:C1ToolbarGroup>
    

    このツールバーグループには1つの C1ToolbarButton が含まれ、その Command プロパティは、ViewModel で定義された ClearCommand に連結されます。
  5. このコマンドは 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" />
    

    UpdateSourceTriggerPropertyChanged に設定することで、ViewModel の TextValue プロパティは、TextBox がフォーカスを失うときだけでなく、Text 値が変更されたときにいつも更新されます。
  6. アプリケーションを実行し、カスタムな RelayCommand の動作を確認します。

    MVVM 設計パターンに準拠すると、UI とビジネスロジックを緩く結合できるため、さまざまなメリットを得ることができます。