5

WPF UIでは、次のコードを介してxamlで参照するRoutedCommandsを使用します。

Command="viewModel:MessageListViewModel.DeleteMessagesCommand"

ViewModelクラスへのこの静的リンクは好きではありません。これは、カスタムICommand実装を作成し、次のような構文を使用するほど良くないと思います。

Command="{Binding DeleteMessagesCommand}"

作成した後、私が行ったことの1つの大きな欠点に気付きました。RoutedCommandsはCommandManagerを利用し、(私には完全に不透明な方法で)CommandManager.RequerySuggestedイベントを起動して、CanExecuteメソッドが自動的に再クエリされるようにします。私のカスタム実装に関しては、CanExecuteは起動時に一度だけ起動され、その後は二度と起動されません。

誰かがこれに対するエレガントな解決策を持っていますか?

4

2 に答える 2

8

CanExecuteChanged次のようにイベントを実装するだけです。

public event EventHandler CanExecuteChanged
{
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
}

コマンドをコントロールに割り当てると、CanExecuteChangedイベントにサブスクライブします。イベントに「リダイレクト」すると、トリガーCommandManager.RequerySuggestedされるたびにコントロールに通知されます。CommandManager.RequerySuggested

于 2010-09-22T10:27:14.817 に答える
0

私はビューモデル バインディング用の Prism の DelegateCommand 実装を非常に好みます ( http://msdn.microsoft.com/en-us/library/ff654132.aspx )。RaiseCanExecuteChanged を呼び出すことにより、すべてのコマンド呼び出し元で CanExecute() を呼び出すことができます。

簡単な使用例:

public class ViewModel
{
   public ViewModel()
   {
      Command = new DelegateCommand<object>(x => CommandAction(), x => CanCommandAction());
   }

   bool state;

   public void ChangeState(bool value)
   {
      state = value;
      Command.RaiseCanExecuteChanged();
   }

   public DelegateCommand<object> Command {get; private set;}

   private void CommandAction()
   {
      //do smthn
   }

   private bool CanCommandAction() { return true == state; }
}

//and binding as usual
Command="{Binding Command}"
于 2010-09-22T10:57:06.993 に答える