CanExecuteCommand是否有任何性能影响?

时间:2011-09-07 14:33:03

标签: wpf mvvm icommand relaycommand

使用ICommand对象的CanExecuteCommand有什么性能影响。方法是一遍又一遍地执行的吗?

我需要迭代大约200个对象的集合,根据它确定是否应该启用绑定到Command的按钮? CanExecuteCommand是否会重复执行,这将使我的应用程序变慢

2 个答案:

答案 0 :(得分:13)

ICommand界面如下:

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

    // one event
    event EventHandler CanExecuteChanged;
}

每当您想要指示WPF应检查/调用CanExecuteChanged方法时,都应引发CanExecute事件。实现ICommand的任何人都应该提出事件,并且需要刷新GUI上的按钮启用状态的人(WPF系统)应该注册并处理事件并调用CanExecute

在Josh Smith的RelayCommand课程中,他使用WPF的内置CommandManager课程来提升CanExecuteChanged

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

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

捎带CommandManager.RequerySuggested以提升ICommand.CanExecuteChanged事件的替代方法是滚动您自己的RelayCommand版本,您可以自行检查并手动引发CanExecuteChanged或者查看Prism框架的DelegateCommand类,它们不与CommandManager绑定,你必须手动引发CanExecuteChanged事件,你可以通过为{创建一个监听器来完成{1}}然后在命令上提升PropertyChanged

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

答案 1 :(得分:0)

对于未来的googlers: 我创建了一个有点不同的命令实现。例如,它绑定到ViewModelBase类的OnPropertyChanged事件,但它也允许View Model为其中的所有Command实例引发CanExecuteChanged事件,无论属性如何变化,例如单向的情况来源绑定方案。 此解决方案是PerrypheralFrameowrk.WPF程序集的一部分,可在nuget和codeplex上使用。仔细看看。 codeplex wiki有详细的文档,程序集中的类也是如此。