Wpf CanExecuteCommand是否有任何性能影响?

Wpf CanExecuteCommand是否有任何性能影响?,wpf,mvvm,icommand,relaycommand,Wpf,Mvvm,Icommand,Relaycommand,使用ICommand对象的CanExecuteCommand会对性能产生什么影响。该方法是否反复执行 我需要遍历大约200个对象的集合,根据这些对象决定是否应该启用绑定到命令的按钮?CanExecuteCommand是否重复执行,这会使我的应用程序变慢接口如下所示: public interface ICommand { // two methods bool CanExecute(object parameter); void Execute(object parame

使用ICommand对象的CanExecuteCommand会对性能产生什么影响。该方法是否反复执行


我需要遍历大约200个对象的集合,根据这些对象决定是否应该启用绑定到命令的按钮?CanExecuteCommand是否重复执行,这会使我的应用程序变慢接口如下所示:

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

    // one event
    event EventHandler CanExecuteChanged;
}
当您希望指示WPF应检查/调用
CanExecute
方法时,应随时引发
CanExecuteChanged
事件。无论谁实现了
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
,每当
CommandManager
认为GUI上发生了有趣的事情时(即使与您的收藏无关),您的
CanExecute
就会被调用。如果您有50个命令,则每次输入关键帧时,它都会重新检查所有50个命令。是的,这可能是一个性能问题。然而,如果
CanExecute
方法中的逻辑非常简单,那么这可能不是问题。要点:不要在
CanExecute
方法中调用数据库或网络API

除了使用
CommandManager.RequerySuggested
引发
ICommand.CanExecuteChanged
事件外,另一种方法是滚动您自己版本的
RelayCommand
,您可以在其中进行自己的检查并手动引发
CanExecuteChanged
,或者看看Prism框架的
DelegateCommand
类,它们不与
CommandManager
相关联,您必须手动引发
CanExecuteChanged
事件,您可以通过为
PropertyChanged
创建一个侦听器,然后在命令上引发
CanExecuteChanged
来实现

不过我同意上面的@Will<代码>中继命令可能会在80%以上的时间内正常工作,不会出现问题。如果您开始发现性能问题,那么您可以创建自己版本的RelayCommand,或者使用Prism
DelegateCommand
并手动提升
CanExecuteChanged

对于未来的谷歌用户: 我创建了一个稍微不同的命令实现。首先,它被绑定到ViewModelBase类的OnPropertyChanged事件,但它也允许视图模型为其中的所有命令实例引发CanExecuteChanged事件,而不管属性是否发生更改,例如在单向源绑定场景中。
此解决方案是PerryPeralFrameOWRk.WPF程序集的一部分,可在nuget和codeplex上获得。查一查。codeplex wiki有详细的文档,程序集中的类也有详细的文档

是的,但前提是你没有过早地优化。你的评论会有点模棱两可。威尔,我也不完全理解。我的验证是大约200个对象的迭代-一个树状视图。它只检查一个简单的属性,在运行一次时不会非常耗时。我担心的是,如果CanExecute被反复触发,代码会变慢。有人能说点什么吗威尔说:你在CanExecute中的代码不应该做太多,因为它确实可以经常调用。但是你不应该只担心这个问题,如果这真的让你的程序变慢了,也就是说,如果你可以测量性能的下降,因为对CanExecute的调用太多了。相关回答如下:谢谢Kendrick和Will,你的回答为我总结了这一点。我将把它放在CanExecute中,并查找任何性能滞后。如果我找到了一个,那么我将研究其他实现