2016-11-14 270 views
2

我做了一些自定义的ICommand实现我自己的,我看到的实现会像这样的很多:为什么人们在ICommands上使用CommandManager.InvalidateRequerySuggested()?

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

protected void RaiseCanExecuteChanged() 
{   
    CommandManager.InvalidateRequerySuggested(); 
} 

至于我可以看到,因为调用RaiseCanExecuteChanged()将触发所有的命令,这是优化不好的代码用户界面来检查他们的ICommand.CanExecute状态,通常我们只是想让他们中的一个来验证它。

我想我读了一次,这是一些WPF ICommands的主代码,比如RoutedCommand,对他们来说它是有道理的,因为他们想要一旦某个控件失去焦点和像这样的事情时自动重新验证所有ICommands,不明白为什么人们将自己的模式重复用于他们自己的ICommand实现。

我心目中的代码是一个简单的事件调用,如:

public event EventHandler CanExecuteChanged; 

protected void RaiseCanExecuteChanged() 
{   
    CanExecuteChanged?.Invoke(this, EventArgs.Empty); 
} 

我测试,一切正常,所以为什么所有的网络上的例子没有实现这么简单的东西吗?我错过了什么吗?

我已阅读有关使用视图被垃圾收集在定期活动,其中CommandManager只使用WeakReferences,这是很好的情况下,强引用的内存泄漏问题,但尽管如此,不存在赢得任何解决方案”在性能上超越内存占用?

+0

http://stackoverflow.com/questions/2281566/is-josh-smiths-implementation-of-the-relaycommand-flawed – ASh

回答

2

为什么网络上的所有示例都没有实现像这样简单的事情?我错过了什么吗?

我猜这主要是由于懒惰...你提出的确实是一个更好的(更高效的)实现。但是,这并不完整:您仍然需要订阅CommandManager.RequerySuggested以提高命令CanExecuteChanged

+0

为什么?我测试了这个,它的工作原理......我错过了哪些情况? – mFeinstein

+0

@mFeinstein,在你测试的情况下,它“起作用”,但调用CommandManager.InvalidateRequerySuggested()不会在你的命令中引发CanExecuteChanged。 –

+0

我没想到它会... – mFeinstein

1

非常简单 - 如果您在ICommand.CanExecute()中执行繁重的工作,那么您正在使用Commands非常糟糕。如果遵循该规则,则实际上不应该致电CommandManager.InvalidateRequerySuggested()

从实用角度来看,它比您所建议的要容易得多。

个人而言,我更倾向于在特定的ViewModel中拨打CommandManager.InvalidateRequerySuggested(),以便对用户的反馈是即时的(即一旦表格完成/有效就启用按钮)。

+0

我很抱歉,但我不明白你的观点,5线解决方案如何比“3线解决方案更容易编程”? – mFeinstein

+0

这很简单,因为您不必每次都在每个受该属性影响的“Command”上调用'RaiseCanExecuteChanged'。 – toadflakz

+0

在这个意义上说,它是,但恕我直言,它的概念有缺陷。 RaiseCanExecuteChanged我相信ViewModel能够通知特定的Command,只有他,他的CanExecute状态发生了变化。 CommandManager是通知所有人的人。我无法想象任何编程的情况下,激活所有对象的目的是激活一个被认为是好的做法。这就像在街上大喊大叫,所有人都会打开门,而不是在你想要的门铃响起。但是,如果你保持你的CanExecute简单并且命令很少,我仍然明白简单。 – mFeinstein

相关问题