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,因此如果两者之间的连接存在且是隐式的,为什么不使它更明确?它还有缺少编译时支持的缺点。如果我将我的按钮挂钩到一个不存在的事件处理程序,编译器会告诉我。如果我绑定到一个不存在的命令,它就不会。
答案 0 :(得分:5)
有很多努力 Silverlight社区保留了XAML 代码隐藏在文件后面,代码免费 可能。真正的动机是什么? 在这背后?
我想说那些希望代码“尽可能免于代码”的人是那些在没有真正理解这一点的情况下跳过MVVM的人。 (或者你误解了他们的观点)。
关键是不要让代码隐藏在代码之外,而是要确保View只负责视觉呈现。可以通过声明方式定义许多视觉方面的事实意味着代码隐藏中的代码更少,但这并不意味着您应该在您觉得有必要的情况下编写代码隐藏,并且不会超出视图的职责范围。< / p>
使用a的优点是什么? 命令而不是事件处理程序?
命令提供至少两个事件处理程序不具备的功能。某些WPF控件知道Command的CanExecute属性,因此例如,当命令无法执行时,可以禁用按钮。设计器和绑定框架也是Command aware。
如果你只想在按钮上调用一个方法,那么使用命令而不是仅仅从事件处理程序调用方法就有 no 的巨大优势。所以不要害怕使用这种方法。 (第三种方法,有利于设计师而不是程序员,是使用Blend 4中的CallMethodAction)。
答案 1 :(得分:3)
它使单元测试和/或TDD更容易。通过使用MVVM和命令,我基本上可以构建我的视图模型并命令TDD样式,并且在没有实际拥有XAML视图的情况下测试大部分视图逻辑。
答案 2 :(得分:1)
你可能会听到许多争论,但实际上只有一个 testability 。除非你为它构建一个单元测试,否则ViewModel几乎不会提供,这反过来意味着你需要创建ViewModel,你可以使用依赖注入,IoC,等等,blah等技术对它进行单元测试。等等。
结果是,如果保持UI代码更加集成,单元测试可以覆盖应用程序代码的大部分内容。
我不一定推荐它,正确地做它需要相当多的设计努力和预见。因此,建立这种方法的成本相当高,但是,提高质量的节省可以很好地抵消这些成本。
答案 3 :(得分:1)
我看到命令的主要优点是当你有执行动作和的双重要求时,验证动作可以执行(即上下文)。换句话说,如果您只是简单地将点击与直接方法调用相关联,我同意,我也认为没有任何优势。但是,如果应该调整单击,并且根据上下文禁用该按钮,则绑定通过CanExecute属性来促进此操作。
这样,不必担心视图中的控件(即具有“查找此控件,并将其设置为禁用因为我们现在无法执行它”的逻辑),我们可以创建命令并简单地确保可以执行返回false。这是可以独立于视图测试的,一旦你绑定它,绑定本身就会负责管理控件的启用属性。