WPF为什么要使用命令而不是事件处理程序?

6
我大约使用了一年的WPFMVVM,但我认为我并没有完全使用MVVM,因为我没有使用命令。到现在为止,我已经做到了所有需要的东西而且效果良好,最重要的是它很清晰简洁。理论上说,MVVM不应该有code behind,但是,为什么要用1000个类来处理每个按钮或事件呢?我真的看不出有什么收益。这只是概念上的问题还是还有其他原因?

MVVM的理论认为不应该有代码后台,不要把每个按钮或事件都写成1000个类,这样会变得非常复杂。你可能需要阅读一本关于WPF中MVVM的书籍。 - user1228
考虑将您的应用程序移植到Windows手机上。您的VM也可以用于WP应用程序。MVVM是一种模式,用于分离代码以实现松耦合。但是您也可以在没有MVVM的情况下构建。所有VM都是可测试的,而您的代码后台则很难测试。绑定和模型验证的魔力是非常好的功能,可以集中精力开发核心。 - Eldho
我脑海中首先想到的是:如果你不使用命令,那么你就不是在做MVVM... 如果你进行适当的设计,你并不需要为每个按钮设置一个命令。 - lokusking
好的,我知道不使用命令意味着不是完整的MVVM,但是这样有什么好处呢?通过使用命令而不是事件处理程序,我可以做些什么呢?这正是我试图理解的,因为我更喜欢简单的代码而不是复杂的代码。从我的观察来看,将事件处理程序用作调用ViewModel方法非常简单,只需要一行代码,而不需要为执行相同方法而编写一个完整的类。 - KillemAll
2个回答

5

我会尝试解释为什么命令很有用。

在MVVM中,视图开发人员(设计师)只负责影响程序的外观,而ViewModel开发人员(程序员)则只关心行为。

想象一下你有一个带有提交按钮的表单。如果该表单没有提交到数据库(例如),那么这是程序员的问题;没有人会责怪设计师。然而,使用事件意味着所有操作都在视图端完成。

这就是命令派上用场的地方。它允许程序员完成逻辑,然后等待设计师将其绑定。程序员可以在没有设计(View)的情况下进行单元测试,并自豪地告诉人们它是可行的。如果出现错误,那么就意味着设计师没有正确地进行绑定。

当然,我相信这里有很多人会独立完成所有工作。在这种情况下,MVVM的使用价值会降低。但是请注意,如果您完全从VS项目中删除所有视图,则您的ViewModel将编译并且完全可用 - 除了没有GUI,也不能接收用户输入。通常,大多数项目需求都是行为上的,因此如果您的ViewModel正常工作,则您几乎已经满足了大部分要求。

最后,我想指出,有代码后台是可以的 - 只要它纯粹只影响外观,而不影响行为。当然,大多数完美主义者希望没有任何代码后台,但在某些情况下这并不总是可能的。


谢谢你的回答,我想如果这是在团队中最有用的唯一原因,并且这个目标是为了在团队中分离角色。但是,如果项目很小,只有一个开发人员,那么使用事件处理程序调用ViewModel中的方法来完成所有逻辑是完全有效的,就像这样:private void Save(object sender, RoutedEventArgs e) { VM myVM = (VM)this.DataContext; myVM.Save(); }我知道这打破了MVVM的概念,但是...这并不是坏事,对吧?我的意思是,视图只调用一个方法,不执行任何逻辑,只是一个调用。 - KillemAll
1
@KillemAll 是的,在独立完成整个项目时,MVVM可能并不是非常有用。我也是C# / WPF / MVVM的新手(几个月的经验),也在独立完成项目。到目前为止,我还没有感受到MVVM带来了多大的差异(除了我需要非常努力地思考如何确保不违反MVVM概念 xD)。 - Jai
1
LOL!! 我同意你关于MVVM很难不破坏的观点。在我的情况下,我真的很喜欢数据绑定和分离角色的概念。唯一让我不太信服的部分是命令,因为调用视图模型方法需要写太多代码 :P lol - KillemAll

4
您的问题太宽泛,无法仅用一句话回答。但是我会回答它,因为我已经使用MVVM工作了很长时间,并且也在没有MVVM的情况下使用WPF。
正如评论所指出的,您的话:“MVVM理论上不应该有后台代码,为什么要用1000个类来处理每个按钮或事件”并不正确。因为使用MVVM有很多好处,这就是为什么这个问题太宽泛的原因。
我很惊讶地听到您到目前为止还没有使用过命令并且正在使用MVVM。因为命令是MVVM的主要部分。使用MVVM的主要好处是它确实帮助我们:
1. 分离视图和模型。没有人希望他们的代码后台(YourPage.xaml.cs)包含所有数据相关的代码、数据操作、设计以及设置用户控件数据等等。如果你想修复代码中的错误或者有人想要审核它,情况会变得更糟。在MVVM中,你可以拥有一个干净的代码后台。事件处理程序和命令之间的区别不大。但是如果你想在按钮点击时更新多个视图,MVVM可以非常整洁和容易地处理它。
2. 数据绑定确保更好的可维护性和可读性。与其设置TextBox1.Text = "Hello World",你可以将Text属性绑定到视图模型属性,并让它在模型更改时更新。这真的是一件很棒的事情。谁想写代码来每次模型更改时更新视图。想象一下现在节省了多少行代码。所有的东西都由数据绑定完成。如果你想在按钮点击时更改10个文本框的内容,绑定非常方便。因此,它减少了紧密耦合。
3. 可测试性:开发人员可以为视图模型和模型创建单元测试,而不使用视图。视图模型的单元测试可以完全使用与视图相同的功能。同时,许多开发人员可以同时使用同一个产品,因为大型视图可以分成较小的视图,并且工作可以非常容易地分配。

2
嗨,我可能有错,但我习惯在代码后台中只调用视图模型的方法,在XAML中完成所有数据绑定,从不像"textbox1.text="hello""这样做。所以我的代码后台非常清晰、简洁,每个事件处理程序只有几行代码。我见过命令的用法,但是要做一个简单的方法调用需要很多代码,所以我在这里问,为什么我应该使用命令?如果在事件处理程序中调用视图模型的方法如此简单和清晰,为什么还需要命令呢? - KillemAll
哈哈,即使解释了这么多,你还在问同样的问题。你完全看完我的回答了吗?由于您的项目不是大规模的,所以您的代码后台只有很少的几行。大型项目可能会有高达2k行的代码后台,并且显然难以管理或维护它们。所以MVVM和命令。实际上,这取决于你。如果你觉得事件处理程序对你的项目很好,那么完全没问题。 - ViVi
2
我也认为ICommand是一个没用的东西,我是一个Web开发人员,做一些WPF/Xamarin的工作,我认为Command本身只是一个委托,但Command是一个类,与VM分离,这意味着你必须将你的方法传递给Command类,让Command知道你的VM属性。我经常使用Vue和Angular,到目前为止,我可以说,使用Command并放弃事件提供的功能是愚蠢的,例如:单击/双击处理,在Vue中只有方法,并且Vue的视图只是“绑定”到VM的方法,因此我们可以根据需要使用任何事件。 - John

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接