代码之家  ›  专栏  ›  技术社区  ›  Sebastian Edelmeier

WPF自定义ICommand实现和CanExecuteChanged事件

  •  5
  • Sebastian Edelmeier  · 技术社区  · 14 年前

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

    Command="viewModel:MessageListViewModel.DeleteMessagesCommand"
    

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

    Command="{Binding DeleteMessagesCommand}"
    

    创建了一个命令后,我注意到我所做的一个主要缺点:routedcommands使用了commandmanager,并且(在某种程度上,它对我来说是完全不透明的)激发commandmanager.requerySuggested事件,以便自动对其canExecute方法进行重新排序。至于我的自定义实现,canexecute只在启动时激发一次,之后再也不会激发。

    有人对此有优雅的解决方案吗?

    2 回复  |  直到 14 年前
        1
  •  8
  •   Thomas Levesque    14 年前

    只需执行 CanExecuteChanged 事件如下:

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

    将命令分配给控件时,它将订阅 已更改CanExecuteChanged 事件。如果你把它“重定向”到 CommandManager.RequerySuggested 事件,控件将在 命令管理器请求建议 被触发。

        2
  •  0
  •   MrDosu    14 年前

    我非常喜欢使用prism的delegatecommand实现来绑定viewModel。( http://msdn.microsoft.com/en-us/library/ff654132.aspx )您可以通过对每个命令调用器调用raiseCanExecute()。

    简单用法示例:

    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}"