我已经开始创建一个 wpf mvvm 应用程序。ViewModel 的一个重要组成部分似乎是一堆 ICommand,它们具有允许视图与 viewmodel 交互的松散耦合方式。
我的问题是,为什么我不能直接绑定到一个方法?
我使用了 Josh Smith 的 ICommand 的 RelayCommand 实现,它允许您将 delgate 注入到 ICommand 对象中,但实际上,是否有一些更简单的方法可以让按钮按下来调用视图模型中的方法?
我是 MVVM 的新手,我相信我需要一些启发
您不能直接绑定到方法,因为Button
(例如)没有接受委托的属性。相反,它具有Command
type 的属性ICommand
。A RelayCommand
(aka DelegateCommand
) 只是ICommand
包装代表的一个。
我看不出为什么视图无法通过标记扩展绑定到视图模型上的特定方法的技术原因:
<Button Command="{ViewModelMethod SomeMethodName}"/>
但是,这会更慢,并且会增加视图和视图模型之间的耦合。如果视图只知道 type 视图模型上的一个属性,ICommand
那么该命令的实现可能会完全改变(或者方法可能被重命名)而视图不知道。
我完全不同意。
调用的速度无关紧要:命令是用户交互,它们从不需要速度。
关于耦合的论点也是有缺陷的。为什么 {Binding MyProperty} 不是耦合,而 {ViewMethod MyMethod} 是耦合?
将特制的“命令”包裹在方法周围的要求是愚蠢的。命令可能是隐蔽的有用实现,但我们已经在 C# 中有方法,用大而笨重的东西替换它们是不对的。
还有关于 MarkupExtension 和 Binding 的事情,真的很难。但这是可以完成的。其实已经搞定了,你可以看看 CodePlex 上的 MethodCall 项目:http: //methodcallthing.codeplex.com/
您可以使用绑定为方法选择“this”,并且可以使用绑定来获取参数。所有这些都是实时的,即在调用命令时计算。另一个好处是方法调用的推送结果,您也可以为此使用绑定(OneWayToSource)。
ICommand 为您提供控制启用所需的 CanExecute。一个简单的委托没有。ICommand 是要走的路。
显然微软需要一个命令来成为一流的东西,可能是因为他们认为拥有 CanExecute 对于大多数应用程序来说是必要的。我不同意并认为 CanExecute 应该只是另一个 DependencyProperty,您将绑定到您的视图模型的属性,但是,嘿,我知道什么?
可能他们还认为有必要将命令的实现与控件的数据上下文分离。再一次,这对我来说似乎没有必要,因为逻辑应该靠近正在操作的数据,这是 OO 的基本原则。
就我个人而言,我避免在 MVVM 中使用命令,因为你必须创建混乱来实现它们。我只是让视图的代码隐藏将事件委托给视图模型。
由于此问题标题的措辞方式,读者可能会在这里寻找替代方法ICommand
,而不仅仅是将 UI 操作直接绑定到 viewModel 方法的方法。(这没有什么价值,因为它留下了如何处理“CanExecute”部分的问题。)
的使用本身ICommand
是有问题的,因为它是Windows.Input
在ICommand
可能会注意到MessageBox
还有大量其他 GUI 功能可用,并可能开始使用它,从而导致混合应用程序逻辑和表示逻辑的混乱局面。
所以,如果你想摆脱using System.Windows
,那么你需要摆脱ICommand
,如果你想摆脱ICommand
,那么你可能会很高兴知道以下内容:
ICommand
。这里的静态是指设计者不需要能够在设计期间使用反射来证明您的命令对象实现了接口ICommand
;取而代之的是,WPF在运行时检查以确保 UI 操作绑定到实际上最终实现了ICommand
.
因此,在您的 viewModels(应用程序逻辑)而不是ICommand
WPF 的接口中,您可以使用Command
自己设备的某些接口,并且您需要确保的是,您将在运行时实例化以实现您的Command
接口的类也ICommand
实现让 WPF 开心。通过这种方式,您可以避免ICommand
在您的 ViewModel 中包含,并且随后您可能能够避免System.Windows
在您的应用程序逻辑中进行引用。