2011-09-07 83 views
5

使用ICommand对象的CanExecuteCommand会带来怎样的性能影响。该方法是否一遍又一遍地执行?CanExecuteCommand有任何性能影响?

我需要迭代约200个对象的集合,根据它来决定绑定到Command的按钮是否应该启用?是否CanExecuteCommand反复地执行,这将让我的应用程序的速度

+4

是的,但前提是您不提前优化。 – Will

+0

您的评论会有点含糊。 – Tyrsius

+0

请问,我也不完全明白。我的验证是大约200个对象的迭代 - 树视图。它只是检查一个简单的属性,并且在运行一次时不会非常耗时。 我的担心是如果CanExecute被重复触发使代码变慢。有人可以抛出一些灯光 – ganeshran

回答

13

ICommand界面如下:

public interface ICommand 
{ 
    // two methods 
    bool CanExecute(object parameter); 
    void Execute(object parameter); 

    // one event 
    event EventHandler CanExecuteChanged; 
} 

CanExecuteChanged事件应提高要表明CanExecute方法应检查任何时间/由WPF调用。实施ICommand的人应该引发该事件,并且需要刷新GUI(WPF系统)上的按钮启用状态的人员应该注册并处理事件,并且它调用CanExecute

在约什 - 史密斯的RelayCommand类,他使用WPF的内置CommandManager课堂上提出CanExecuteChanged

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

从本质上说,WPF的CommandManager是一个单是聆听各种路由事件:KeyUpEvent,MouseUpEvent,等等......然后通过提高其RequerySuggested事件告诉每个人“嗨发生了一些有趣的事情”。因此,如果您使用的是RelayCommand,那么您的CanExecute每次都会在CommandManager认为在GUI上发生了一些有趣的事情(即使它与您的收藏无关)。如果你有50条命令,每次键入时,它会重新检查所有50条命令。所以是的,这可能是一个性能问题。但是,如果您的CanExecute方法中的逻辑非常简单,那么这可能不是问题。建议点:不要在CanExecute方法中进行数据库或网络API调用。

以捎带关闭CommandManager.RequerySuggested提高ICommand.CanExecuteChanged事件的另一种方法是手工卷制自己的RelayCommand版本,你做你自己的检查和人工提高CanExecuteChanged,或看棱镜框架的DelegateCommand类,他们不打领带到CommandManager,您必须手动提高CanExecuteChanged事件,您可以通过创建PropertyChanged的侦听器,然后在该命令上增加CanExecuteChanged来完成该事件。

虽然我同意@Will的意思。 RelayCommand可能会工作超过80%的时间没有问题。如果您确实开始发现性能问题,那么您可以创建自己的RelayCommand版本,或者使用Prism DelegateCommand并手动提升CanExecuteChanged

+0

相关的答案在这里:http://stackoverflow.com/questions/6634777/what-is-the-actual-task-of-canexecutechanged-and-commandmanager-requerysuggested – Kendrick

+0

谢谢肯德里克和威尔,你的回答总结为我。我将把它放在CanExecute中并寻找任何性能滞后。如果我找到一个,那么会查看其他实现 – ganeshran

0

对于未来的谷歌浏览器: 我创建了一个有点不同的命令实现。首先,它绑定到ViewModelBase类的OnPropertyChanged事件,但它也允许View模型为其中的所有Command实例引发CanExecuteChanged事件,而不管属性是否改变,例如One Way到源绑定方案。 此解决方案是PerrypheralFrameowrk.WPF程序集的一部分,可在nuget和codeplex上使用。看看它。 codeplex wiki有详细的文档,组件中的类也是如此。