MVVM ICommand alternative
我已经开始创建一个wpf mvvm应用程序。 ViewModel的一个重要组成部分是一系列ICommands,它们有一个松散耦合的方式允许视图与视图模型交互。MVVM ICommand alternative
我的问题是,为什么我不能直接绑定到一个方法?
我已经使用了Josh Smith的ICommand的RelayCommand实现,它允许你将一个delgates注入到一个ICommand对象中,但是真的有一些更简单的方法来允许按钮push来调用viewmodel中的一个方法吗?
我是新来的MVVM,我相信我需要一些启示
不能直接绑定到一个方法,因为Button
(例如)不具有接受委托的属性。相反,它有一个Command
类型的属性ICommand
。 A RelayCommand
(又名DelegateCommand
)只是包装代表的ICommand
。
我看不出有什么技术原因,它不会是可能的观点由标记扩展的方式绑定到视图模型具体方法:
<Button Command="{ViewModelMethod SomeMethodName}"/>
然而,这将是慢,会增加视图和视图模型之间的耦合。如果视图仅知道类型为ICommand
的视图模型上的属性,那么该命令的实现可能完全改变(或者方法可以被重命名)而不会意识到视图。
为什么它会变慢?它需要使用反射吗?但我确实了解你提到的耦合问题。 – Jose 2009-06-04 18:13:28
嗯,其实我不认为这会慢很多,因为绑定到viewmodel命令也使用反射。然而,这种方法有一个缺点:由于ViewModelCommand标记扩展不是绑定,所以当ViewModel改变时它不会被更新:它只会被评估一次(除非它挂钩到DataContextChanged事件以重新评估,但那是另一回事。 ..) – 2009-06-06 15:14:09
首先,我说“慢”,而不是“慢”。重要的区别。其次,我在谈论解决方案和调用方法,而不是绑定本身。使用虚拟机创建的代理将比反思性地解析视图中的方法更快。因此,除了所有其他的退步之外,从视角来看这样做会更慢。 – 2009-06-06 17:11:25
我完全不同意。
调用的速度没有意义:命令是用户交互,他们从不需要速度。
关于耦合的论点也有缺陷。为什么{Binding MyProperty}不是耦合而是{ViewMethod MyMethod}?
将特制“命令”包裹在方法中的要求是愚蠢的。命令在封面下可能是有用的实现,但是我们已经在C#中使用了方法,并用大而笨重的代码替换它们。
而关于MarkupExtension和Binding的东西,确实很难。但这是可以完成的。实际上,您可以看看CodePlex上的MethodCall项目: http://methodcallthing.codeplex.com/
您可以使用绑定为该方法选择“this”,并且可以使用绑定来获取参数。所有这些都是实时的,即在命令被调用时计算。另一个附加功能是方法调用的推出结果,您也可以使用绑定(OneWayToSource)。
ICommand为您提供了CanExecute,这是控制启用所必需的。一个简单的代表不会。 ICommand是要走的路。
显然,微软需要一个Command作为一流的东西,可能是因为他们觉得CanExecute对于大多数应用程序来说是必需的。我不同意,并认为CanExecute应该是另一个DependencyProperty,你将绑定到你的视图模型的属性,但是,嘿,我知道什么?
可能他们也认为需要从控件的datacontext中分离一个命令的实现。然而,这对我来说似乎没有必要,因为逻辑应该接近正在运行的数据,这是OO的基本原则。
个人而言,我避免在MVVM中使用命令,因为您必须创建它们来实现它们。我只是让视图的代码隐藏事件直到视图模型。
您可以绑定到一个方法: