2010-09-22 115 views
5

,我用我通过下面的代码是指在我的XAML RoutedCommands:WPF自定义ICommand的执行情况和我的WPF UI的CanExecuteChanged事件

Command="viewModel:MessageListViewModel.DeleteMessagesCommand" 

我不喜欢这样的静态链接到我的ViewModel类,我觉得这不是像你一样创建一个自定义的ICommand实现和使用类似下面的语法

Command="{Binding DeleteMessagesCommand}" 

已经创建了一个,我发现我已经做了什么一个主要的缺点:RoutedCommands利用命令管理和(在某种程度上,这对我来说是完全不透明的)着火CommandManager.RequerySuggested事件,以便它们的CanExecute方法自动重新查询。至于我的自定义实现,CanExecute仅在启动时启动一次,之后再也不会启动。

有没有人有这个优雅的解决方案?

回答

8

只需实现CanExecuteChanged事件如下:

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

当您指定的命令来控制,它订阅了CanExecuteChanged事件。如果“重定向”它的CommandManager.RequerySuggested事件,每当CommandManager.RequerySuggested触发控制将被通报。

+0

多谢这个伟大的和简洁的答复!奇迹般有效。你有没有机会知道何时以及为什么RequerySuggested被解雇? – 2010-09-22 11:35:18

+1

不完全,但我似乎经常发生... – 2010-09-22 11:43:57

+0

好的,再次感谢! – 2010-09-22 11:54:57

0

我非常喜欢约束力的视图模型的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}" 
+0

感谢您的想法,但是 - 我们已经学会了 - “以极大的权力越大,责任越大” ...... – 2010-09-22 11:53:09

+0

对不起,压得太很快进入。我的意思是:在给我机会的同时,它也迫使我这样做,以获得通知。 – 2010-09-22 11:54:01