使用ICommand对象的CanExecuteCommand会带来什么性能影响。这个方法是一遍又一遍地执行吗?
我需要遍历大约200个对象的集合,根据这个集合来决定是否应该启用绑定到Command的按钮?是否会重复执行CanExecuteCommand,这会使应用程序变慢
发布于 2011-09-07 15:28:56
ICommand
接口如下所示:
public interface ICommand
{
// two methods
bool CanExecute(object parameter);
void Execute(object parameter);
// one event
event EventHandler CanExecuteChanged;
}
每当您希望指示CanExecute
方法应由WPF检查/调用时,都应引发CanExecuteChanged
事件。实现ICommand
的任何人都应该引发事件,而需要刷新图形用户界面( 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
,那么每当CommandManager
认为图形用户界面上发生了有趣的事情时,都会调用您的CanExecute
(即使它与您的集合没有任何关系)。如果你有50个命令,每次你按下键盘,它都会重新检查所有50个命令。所以,是的,这可能是一个性能问题。但是,如果您的CanExecute
方法中的逻辑真的很简单,那么这可能不是问题。要点:不要在CanExecute
方法中进行数据库或网络应用程序接口调用。
利用CommandManager.RequerySuggested
引发ICommand.CanExecuteChanged
事件的另一种方法是使用您自己的RelayCommand
版本,您可以在其中进行自己的检查并手动引发CanExecuteChanged
,或者查看Prism框架的DelegateCommand
类,在该类中,它们不绑定到CommandManager
中,您必须手动引发CanExecuteChanged
事件,您可以通过为PropertyChanged
创建一个侦听器,然后在命令上引发CanExecuteChanged
来实现这一点。
我同意上面提到的@Will。RelayCommand
可能会在80%以上的时间内没有问题地工作。如果您确实开始发现性能问题,那么您可以创建自己的RelayCommand版本,或者使用棱镜DelegateCommand
并手动提升CanExecuteChanged
。
发布于 2014-11-01 21:56:52
对于未来的googlers:我已经创建了一个有点不同的命令实现。例如,它被绑定到ViewModelBase类的OnPropertyChanged事件,但它也允许视图模型为其中的所有命令实例引发CanExecuteChanged事件,而不管属性的更改,例如在单向源代码绑定方案的情况下。此解决方案是PerrypheralFrameowrk.WPF程序集的一部分,可在nuget和Codeplex上获得。查一查。codeplex wiki有详细的文档,程序集中的类也有详细的文档。
https://stackoverflow.com/questions/7335668
复制