2009-03-16 25 views

答えて

22

違いは、RelayCommandが代理人を受け入れることができる点です。 ViewModelの外部にRelayCommandを定義することができます。 ViewModelは、コマンドを作成してコントロールなどのUIオブジェクトにバインドするときに、コマンドにデリゲートを追加できます。代理人は、ViewModelのスコープ内で定義されているように、ViewModelのプライベート変数にアクセスできます。

ViewModelに含まれるコードの量を減らすために使用されます。傾向は、ViewModel内でネストされたクラスとしてRoutedコマンドを定義することです。この2つの機能は、それ以外は同様です。

67

RoutedCommandはWPFの一部ですが、RelayCommandはWPF Disciple、Josh Smithによって作成されました。

本当に、RS Conleyはいくつかの違いを説明しました。主な相違点は、RoutedCommandはRouteEventを使用して、コマンドのCommandBindingが見つかるまでRoutedEventを使用してRelayCommandがルーティングを行わず、代わりに一部のデリゲートを直接実行するICommand実装です。 M-V-VMシナリオではRelayCommand(PrismのDelegateCommand)が多分もっと良い選択です。 MVVMでRelayCommandとRoutedCommandの使用私のための主な違いは以下の通りですについて

34

:コードの

場所

RelayCommandはICommandの財産として、(あなたが任意のクラスでコマンドを実装することができますデリゲートと一緒に)、これは通常、コマンドを呼び出すコントロールにデータバインドされます。このクラスはViewModelです。 ルーティングされたコマンドを使用する場合は、CommandBinding要素の属性によってメソッドが指定されているため、コントロールのコードビヘイビアにコマンドに関連するメソッドを実装する必要があります。厳密なMVVMには "空の"コードビハインドファイルがあることを意味すると想定されますが、実際にはMVVMで標準のルーティングコマンドを使用する可能性はありません。 RSコンリーはRelayCommandはViewModelに外RelayCommandを定義することができますことを、言っ

は正しいですが、すべての最初のそれはあなたがRoutedCommandのにはない内部のViewModel、それを定義することができます。一方ルーティング

、(前に言ったように)RelayCommandsがあなたのインタフェースが単一のViewModelに基づいている限り、問題はありませんこれは、木を経由サポートしていません。そうでない場合、たとえば、独自のviewModelを持つアイテムのコレクションがあり、親要素の各項目の子ViewModelのコマンドを一度に呼び出す場合は、ルーティングを使用する必要があります(CompositeCommandsも参照) 。

まったく、標準のRoutedCommandsは厳格なMVVMでは使用できません。 RelayコマンドはMVVMには最適ですが、必要なルーティングをサポートしていません。

+0

あなたの説明とCompositeCommandsへの参照の余分な深さをお寄せいただき、ありがとうございました。 –

13

厳密なMVVMではRoutedCommandsが完全に合法であると主張します。 RelayCommandsはシンプルさのためにしばしば好まれますが、RoutedCommandsは組織的な利点を提供することがあります。たとえば、共有のICommandインスタンスに複数の異なるビューを接続し、そのコマンドを基になるViewModelに直接公開しないでください。

厳密なMVVMはコードビハインドの使用を禁止していないことに注意してください。それが真実であれば、ビュー内にカスタム依存プロパティーを決して定義することはできませんでした。

  1. カスタムコマンドの静的RoutedCommandのインスタンスを宣言:次の手順を実行することができ、厳密なMVVMフレームワーク内でRoutedCommandのを使用するためには

    。 ApplicationCommandsクラスから事前定義されたコマンドを使用する場合は、この手順をスキップできます。たとえば:

    public static class MyCommands { 
        public static RoutedCommand MyCustomCommand = new RoutedCommand(); 
    } 
    
  2. は、XAMLを使用してRoutedCommandのに必要な景色を取り付けます

    <Button Command="{x:Static local:MyCommands.MyCustomCommand}" /> 
    
  3. ニーズ(ViewModelには、コマンドの機能を実装方すなわち)、適切なのViewModelにバインドされている、あなたの意見の一つ

    public partial class MainView : UserControl 
    { 
        public static readonly DependencyProperty MyCustomCommandProperty = 
         DependencyProperty.Register("MyCustomCommand", 
         typeof(ICommand), typeof(MainView), new UIPropertyMetadata(null)); 
    
        public ICommand MyCustomCommand { 
         get { return (ICommand)GetValue(MyCustomCommandProperty); } 
         set { SetValue(MyCustomCommandProperty, value); } 
        } 
    
  4. のTh:あなたのViewModelの実装にバインドされるカスタムたDependencyPropertyを露出させます関連するイベントハンドラがちょうどステップ3で宣言された依存関係プロパティからのICommandに委譲しますあなたのビューのコードビハインドで

    <UserControl.CommandBindings> 
        <CommandBinding Command="{x:Static local:MyCommands.MyCustomCommand}" 
            CanExecute="MyCustomCommand_CanExecute" 
            Executed="MyCustomCommand_Executed" 
            /> 
    </UserControl.CommandBindings> 
    

    :E同じビューはXAMLでは、ステップ1からRoutedCommandのに自分自身をバインドする必要があります:

    private void MyCustomCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e) { 
        var command = this.MyCustomCommand; 
        if (command != null) { 
         e.Handled = true; 
         e.CanExecute = command.CanExecute(e.Parameter); 
        } 
    } 
    private void MyCustomCommand_Executed(object sender, ExecutedRoutedEventArgs e) { 
        var command = this.MyCustomCommand; 
        if (command != null) { 
         e.Handled = true; 
         command.Execute(e.Parameter); 
        } 
    } 
    
  5. 最後に、XAMLでカスタム依存関係プロパティに(ICommandのでなければなりません)あなたのViewModelのコマンドの実装をバインドします

    <local:MainView DataContext="{Binding MainViewModel}" 
           MyCustomCommand="{Binding CustomCommand}" /> 
    

このアプローチの利点は、ViewModelはICommandインターフェイスの1つの実装(RelayCommandでも構いません)だけで済みますが、RouteCommand経由で任意の数のビューを接続することができますそのViewModelに直接バインドされています。

残念ながら、ICommand.CanExecuteChangedイベントが機能しないという欠点があります。 ViewModelがCanExecuteプロパティをリフレッシュするようにViewModelを設定するには、CommandManager.InvalidateRequerySuggested()を呼び出す必要があります。

関連する問題