10

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,所以如果两者之间的联系存在并且是隐式的,为什么不让它更明确呢?它还具有失去编译时支持的缺点。如果我将按钮连接到不存在的事件处理程序,编译器会告诉我。如果我绑定到一个不存在的命令,它不会。

4

4 回答 4

5

Silverlight 社区为使 XAML 的代码隐藏在文件中尽可能地无代码而付出了很多努力。这背后的真正动机是什么?

我想说那些想要“尽可能无代码”背后的代码的人是那些在没有真正理解重点的情况下跳上 MVVM 潮流的人。(或者你误解了他们的观点)。

关键不是要让代码隐藏没有代码,而是要确保 View 只负责视觉呈现。可以以声明方式定义许多视觉方面的事实意味着代码隐藏中的代码更少,但这并不意味着您应该犹豫在您认为有必要的地方编写代码隐藏并且不会超出视图的职责范围。

使用命令而不是事件处理程序有什么好处?

命令至少提供了两个事件处理程序没有的功能。一些 WPF 控件知道 Command 的 CanExecute 属性,例如,当命令不可执行时,可以禁用按钮。设计器和绑定框架也是命令感知的。

如果您只想在按下按钮时调用方法,那么使用命令而不是仅从事件处理程序调用方法并没有太大的优势。所以不要害怕使用这种方法。(第三种有利于设计师而不是程序员的方法是使用 Blend 4 中的 CallMethodAction)。

于 2010-07-31T06:37:58.730 回答
3

它使单元测试和/或 TDD 更容易。通过使用 MVVM 和命令,我基本上可以构建我的视图模型和命令 TDD 样式,并在根本没有实际 XAML 视图的情况下测试大部分视图逻辑。

于 2010-07-27T15:42:16.507 回答
1

你可能会听到很多关于它的论点,但实际上只有一个,可测试性。除非您为其构建单元测试,否则 ViewModel 交付很少,这反过来意味着您需要使用依赖注入、IoC、blah、blah 等技术以可以对其进行单元测试的方式创建 ViewModel , ETC。

结果是单元测试可以覆盖应用程序代码的更大部分,而不是保持 UI 代码更加集成。

我不一定推荐它,要正确地做到这一点需要相当大的设计努力和远见。因此,构建这种方法的成本相当高,但是,提高质量所节省的成本可能会很好地抵消这些成本。

于 2010-07-27T15:48:03.607 回答
1

我看到该命令的主要优点是当您有执行动作验证动作可以执行的双重要求时(即上下文)。换句话说,如果您只是将点击与直接的方法调用联系起来,我同意,我也没有看到任何优势。但是,如果单击应该有条件,并且基于上下文禁用按钮,则绑定通过 CanExecute 属性促进了这一点。

这样,我们不必担心视图中的控件(即具有“找到此控件,并将其设置为禁用,因为我们现在无法执行它)的逻辑,我们可以创建一个命令并简单地确保可以执行返回false。这是独立于视图的可测试的,一旦你绑定它,绑定本身负责管理控件的启用属性。

于 2010-07-27T16:42:28.133 回答