5

在我的 WPF UI 中,我通过以下代码使用我在我的 xaml 中引用的 RoutedCommands:

Command="viewModel:MessageListViewModel.DeleteMessagesCommand"

我不喜欢这个指向我的 ViewModel 类的静态链接,我认为这不如创建自定义 ICommand 实现并使用如下语法

Command="{Binding DeleteMessagesCommand}"

创建了一个后,我注意到我所做的一个主要缺点: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 回答