将代码排除在 XAML 代码之外的真正优势是什么?
Silverlight 社区付出了很多努力来使 XAML 的代码隐藏文件尽可能不含代码。这背后的真正动机是什么?
例如,使用命令而不是事件处理程序有什么优点?如果我有
<Button x:Name="SaveButton" Content="Save" Click="SaveButton_Click" />
...
private void SaveButton_Click(object sender, RoutedEventArgs e) {
_myViewModel.SaveChanges();
}
那么为什么这是首选?
<Button x:Name="SaveButton" Content="Save" Command="{Binding SaveCommand}" />
显然,我的视图模型中的 SaveCommand
将有效地调用 SaveChanges()
。
这可能会导致视图是 100% XAML 的情况,甚至在 XAML 中实例化视图模型,视图和视图模型之间的连接完全通过绑定完成。当然是干净了,但是还有什么呢?灵活的?为什么?视图仍然需要使用正确的 ViewModel,因此如果两者之间的联系存在并且是隐式的,为什么不使其更明确呢?它还具有失去编译时支持的缺点。如果我将按钮连接到不存在的事件处理程序,编译器会告诉我。如果我绑定到不存在的命令,则不会。
There is a lot of effort in the Silverlight community to keep a XAML's code behind file as free of code as possible. What is the real motivation behind this?
For example, what is the advantage of using a command instead of an event handler? If I have
<Button x:Name="SaveButton" Content="Save" Click="SaveButton_Click" />
...
private void SaveButton_Click(object sender, RoutedEventArgs e) {
_myViewModel.SaveChanges();
}
Then why is this prefered?
<Button x:Name="SaveButton" Content="Save" Command="{Binding SaveCommand}" />
Where obviously the SaveCommand
in my view model is effectively going to invoke SaveChanges()
.
This can lead to situations where the view is 100% XAML, even instantiating the view model in XAML, and the connections between the view and view model are completely done through binding. Sure it's clean, but what else is it? Flexible? Why? the view still needs to work with the proper ViewModel, so if the connection between the two exists and is implicit, why not make it more explicit? It also has the disadvantage of losing compile time support. If I hook my button up to an event handler that doesn't exist, the compiler will tell me. It won't if I bind to a non-existent command.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可能会听到很多对此的争论,但实际上只有一个,可测试性。 ViewModel 提供的功能很少,除非您为其构建单元测试,这反过来意味着您需要以可以对其进行单元测试的方式创建 ViewModel,使用诸如依赖注入、IoC 等技术 。
结果是单元测试可以覆盖应用程序代码的更大部分,而如果您保持 UI 代码更加集成,则无法实现这一点
我不一定推荐它,要正确地做到这一点需要大量的设计工作和深思熟虑。因此,构建这种方法的成本相当高,但是,提高质量所节省的成本很可能抵消这些成本。
There are probably many arguments you might hear for it but pragmatically there is only one, testability. A ViewModel delivers little unless you build a unit test for it, which in turn implies that you would need to create the ViewModel in such a way that you can unit test it, using techniques such as dependency injection, IoC, blah, blah, etc, etc.
The result is that unit tests can cover a larger part of your applications code than you could achieve had you kept the UI code more integrated.
I'm not necessarily recommending it, to do it properly takes considerable design effort and forethought. Hence the costs in building such an approach are quite high, however, the savings of the increased quality may well offset those costs.
我认为该命令的主要优点是当您有执行操作和验证该操作可以执行(即上下文)的双重要求时。换句话说,如果您只是将点击与直接方法调用链接起来,我同意,我也看不到任何优势。但是,如果应该对单击进行调节,并且根据上下文禁用按钮,则绑定可以通过 CanExecute 属性来实现这一点。
这样,我们就可以创建一个命令,并简单地确保可以这可以独立于视图进行测试,一旦绑定它,绑定本身就会负责管理控件的启用属性。
The main advantage I see with the command is when you have the dual requirement of executing an action and validating that the action can execute (i.e. context). In other words, if you are simply linking the click with a straight method call, I agree, I see no advantage either. If the click should be conditioned, however, and the button disabled based on context, then the binding facilitates this through the CanExecute property.
This way, instead of having to worry about controls in the view (i.e. having the logic that says "find this control, and set it to disabled because we can't execute it right now) we can create a command and simply ensure that can execute returns false. This is testable independent of the view and once you do bind it, the binding itself takes care of managing the control's enabled property.
我想说的是,那些希望背后的代码“尽可能无代码”的人是那些没有真正理解要点就加入了 MVVM 潮流的人。 (要么就是你误解了他们的观点)。
重点不是让代码隐藏没有代码,而是确保视图只负责视觉呈现。事实上,许多视觉方面可以以声明方式定义,这意味着隐藏代码中的代码更少,但这并不意味着您应该犹豫是否在您认为必要且不超出视图职责的情况下编写隐藏代码。
命令至少提供两种事件处理程序不具备的功能。某些 WPF 控件可以识别命令的 CanExecute 属性,因此,例如,当命令不可执行时,可以禁用按钮。设计器和绑定框架也是命令感知的。
如果您只想在按下按钮时调用方法,那么使用命令而不是仅从事件处理程序调用该方法没有很大的优势。所以不要害怕使用这种方法。 (第三种方法是使用 Blend 4 中的 CallMethodAction,它对设计人员比程序员更有利)。
I would say that people who want the code behind "as free of code as possible" are those who have jumped on the MVVM bandwagon without really getting the point. (Either that or you have misinterpreted their point).
The point is not to keep the code-behind free of code, but to make sure that the View is only responsible for visual presentation. That fact that many visual aspects can be defined declaratively means there is less code in the code-behind, but it does not mean you should hesitate to write code-behind where you feel it is necessary and does not transgress outside the view's responsibilities.
A Command offers at least two capabilities that an event handler doesn't. Some WPF controls are aware of the CanExecute property of the Command, so for example a button can be disabled when the command is not available to execute. Also the designer and binding framework are Command aware.
If you just want to call a method on a button press there is no great advantage to using Commands instead of just calling the method from an event handler. So don't be afraid to use this approach. (A third approach, which favours designer over programmer, is to use the CallMethodAction from Blend 4).
它使单元测试和/或 TDD 更容易。通过使用 MVVM 和命令,我基本上可以构建视图模型和 TDD 风格的命令,并测试大部分视图逻辑,而无需实际使用 XAML 视图。
It makes unit testing and / or TDD easier. By using MVVM and commanding, I can essentially build my view model and commands TDD style and have most of the view logic tested without actually having the XAML view at all.