RelayCommand
的一个非常常见的实现似乎包括以下几行:
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
这对我来说似乎非常有缺陷,因为CommandManager
是WPF组件,通常我的命令位于viewmodel类中。由于viewmodel不应该知道视图并且应该使用不同的框架等,这对我来说似乎很奇怪。例如,如果将viewmodel分离到一个不知道WPF名称空间(例如PCL)的额外项目中,则甚至不可能实现此实现。
此实现是否违反MVVM模式?
或者您可能会以某种方式将RelayCommand
放在您的视图中?
如果这确实存在缺陷,是否有最佳实践解决方案可以解决这个问题?
答案 0 :(得分:3)
这是一个简单快捷的方法。脏实现主要仅用于不将教程绑定到特定MVVM框架的教程案例,而是作为一个通用的自助MVVM教程。
这种方法 - 除紧耦合外 - 还有其他几个缺点。
调用CommandManager.InvalidateRequerySuggested()
方法时,将调用每个命令的CanExecute
方法。如果您的应用程序中有100个命令,则会对WPF应用程序的性能产生严重影响。
我个人总是建议使用成熟的MVVM框架(Prism是我最喜欢的LoB应用程序)。这些命令通常不以这种方式实现,但是您调用MyCommand.OnCanExecuteChanged()
(在Prism的情况下)为一个命令触发CanExecute
验证。
如果你有复合或多个相互依赖的命令,你可以自己在代码中绑定它,即在视图中存储相关命令列表并循环使用它或者注册它们的OnCanExecuteChanged()
方法到多播委托并调用它。
此实现是否违反了MVVM模式?
技术上是的。
或者您是否可以以某种方式将RelayCommand放在您的视图中?
不是真的,虽然你可以用外部工厂来抽象它,但似乎没有意义(见上面的问题)
如果这确实存在缺陷,是否有解决此问题的最佳实践实施?
无论如何都不要对命令状态进行全局失效。自己绑定命令,需要将执行状态绑定在一起。