我正在开发一个WPF应用程序并且我非常了解命令模式,但我发现MVVM的命令模式有几种不同的实现。在他的WPF示例应用程序中有Josh Smith的实现,来自Prism的DelegateCommand
以及CommandBindings
实现。
我的问题是,在MVVM中使用命令的普遍接受的最佳做法是什么?我的应用程序使用Prism,因此我们可以使用DelegateCommand
。
我团队的开发人员正在争论哪种方法“最好”。有些人不喜欢为每个命令生成的众多.cs文件,有些人则更喜欢通过CommandBindings
连接所有内容。我不知所措。任何人都能解释一下吗?
答案 0 :(得分:3)
嗯 - 我认为没有 解决方案。
CommandBindings不易测试,并且在ViewModel中为WPF类引入了一个不太好的依赖项。 所以我不会用它们。
DelegateCommand和CommandSinkCommand(Josh Smith的解决方案)都是IMO的好方法。它们并没有真正的不同,它们都没有优于另一个。 但是,我注意到,当命令路由变得更复杂时(特别是涉及DataTemplates时),CommandSink版本始终不起作用。
您甚至可以将它们组合在一起:使用DelegateCommand并另外使用JoshSmith版本 - 这样您就可以结合两者的优点。 你唯一需要的是一些辅助类 - 实际上并不难实现。
更重要的是您的应用程序中的合规性:如果您决定要使用什么,则应该在整个应用程序中遵循这种方式。
答案 1 :(得分:2)
要考虑两点:
不同MVVM框架提供的命令,如CommandSinkCommand或SimpleCommand(来自Cinch)等,可以像普通的ICommands一样工作。特别是,只要WPF认为发生了可能导致UI更改的事情,就会评估CanExecute处理程序。您也可以通过CommandManager.InvalidateRequerySuggested()
手动强制执行此操作。
与此相反,DelegateCommands<>除非您在命令上手动调用RaiseCanExecuteChanged()
,否则Prism不会调用CanExecute处理程序。如果您希望更改此设置,以便在通常重新获取命令时也会触发它,请参阅http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=47338处的代码
编辑:
第二点:MVVM框架的命令通常接受一个对象作为命令参数。相反,DelegateCommands<>棱镜的类型更强(虽然如果你愿意,你当然可以有一个DelegateCommands)。