7

我正在开发一个 WPF 应用程序,并且我非常了解命令模式,但我发现 MVVM 的命令模式有几种不同的实现。Josh Smith 在他的 WPF 示例应用程序中的实现,DelegateCommand来自 Prism 和CommandBindings实现。

我的问题是,在 MVVM 中使用命令的公认最佳实践是什么?我的应用程序使用 Prism,因此DelegateCommand我们可以使用。

我团队的开发人员正在争论哪种方法是“最好的”。有些人不喜欢为每个命令生成的大量 .cs 文件,而另一些人则喜欢通过 .cs 连接所有内容CommandBindings。我不知所措。任何人都可以解释一下吗?

4

2 回答 2

3

好吧 - 我认为没有解决方案。

CommandBindings 不是那么容易测试的,并且在 ViewModel 中引入了对 WPF 类的依赖,这不是很好。所以我不会使用它们。

DelegateCommand 和 CommandSinkCommand(Josh Smith 的解决方案)都是 IMO 的好方法。它们并没有真正的不同,也没有一个优于另一个。不过,我注意到,当命令路由变得更加复杂时(尤其是涉及 DataTemplates 时),CommandSink 版本并不总是有效。

您甚至可以将它们结合起来:使用 DelegateCommand 并另外使用 JoshSmith 版本 - 这样您就可以结合两者的优点。您唯一需要的是一些辅助类——实现起来并不难。

更重要的是应用程序的一致性:如果您决定要使用什么,则应该在整个应用程序中遵循这种方式。

于 2009-12-15T16:31:21.007 回答
2

需要考虑的两点:

不同 MVVM 框架提供的命令,例如 CommandSinkCommand 或 SimpleCommand(来自 Cinch)等,与普通 ICommand 一样工作。特别是,只要 WPF 认为发生了可能导致 UI 更改的事情,就会评估 CanExecute 处理程序。您也可以手动强制执行此操作CommandManager.InvalidateRequerySuggested()

与此相反,Prism 的 DelegateCommands<> 不会调用 CanExecute 处理程序,除非您手动调用RaiseCanExecuteChanged()该命令。如果您希望更改此设置,以便在正常请求命令时也会触发它,请参阅http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=47338处的代码

编辑:

第二点:MVVM 框架的命令通常接受一个对象作为命令参数。相比之下,Prism 的 DelegateCommands<> 的类型更强(尽管如果您愿意,当然可以拥有 DelegateCommands)。

于 2010-06-02T12:32:04.773 回答