传统的MVVM实现是否毫无意义?我正在创建一个新的应用程序,我考虑了Windows窗体和WPF.我 Select WPF是因为它经得起future 的考验,并且提供了很大的灵活性.使用XAML,代码更少,更容易对UI进行重大更改.

由于WPF的 Select 是显而易见的,我想我也可以使用MVVM作为我的应用程序架构,因为它提供了可混合性、分离问题和单元可测试性.从理论上讲,它看起来很漂亮,就像UI编程的圣杯.这一短暂的冒险;然而,却变成了一件真正令人头疼的事情. 不出所料,在实践中,我发现我用一个问题换了另一个问题.我往往是一个痴迷的程序员,因为我想用正确的方式做事,这样我就可以得到正确的结果,并有可能成为一名更好的程序员.MVVM模式刚刚没有通过我的生产力测试,而且刚刚变成了一个讨厌的大麻烦!

一个明显的例子是添加对Modal对话框的支持.正确的方法是打开一个对话框,并将其绑定到视图模型.要让它发挥作用是很困难的.为了从MVVM模式中获益,您必须将代码分布在应用程序各层的多个位置.您还必须使用深奥的编程 struct ,如模板和Lamba表达式.让你目不转睛地盯着屏幕挠头的东西.正如我最近发现的那样,这使得维护和调试成为等待发生的噩梦.我有一个关于框工作正常,直到我得到一个异常,我第二次调用它,说它不能再次显示对话框,一旦它被关闭.我必须为对话窗口添加一个关闭功能的事件处理程序,在它的IDialogView实现中添加另一个事件处理程序,最后在IDialogViewModel中添加另一个事件处理程序.我以为MVVM会把我们从这种奢侈的黑客攻击中解救出来!

有好几个人对这个问题有着相互竞争的解决方案,他们都是黑客,没有提供一个干净、易于重用、优雅的解决方案.大多数MVVM工具包都掩盖了对话框,当它们处理对话框时,它们只是警告框,不需要自定义界面或视图模型.

我打算放弃MVVM视图模式,至少放弃它的正统实现.你怎么认为?如果你有麻烦,值得吗?我只是一个不称职的程序员,还是MVVM不像人们所宣传的那样?

推荐答案

如果我的答案太长了,很抱歉,但是不要怪我!你的问题也很长.

In summary, MVVM is not pointless.

一个明显的例子是增加了 支持模态对话框.这个 正确的方法是打开一个对话框 并将其绑定到视图模型.获取 这件事很难做.

是的,确实如此.
但是,MVVM为您提供了一种将UI外观与其逻辑分开的方法.没有人强迫您在任何地方使用它,也没有人拿枪指着您的额头让您为所有东西创建单独的ViewModel.

以下是我针对这个特定示例的解决方案:

为了从MVVM模式中获益,必须在应用程序的各个层中的多个位置分发代码.您还必须使用一些深奥的编程 struct ,比如模板和lamba表达式.

嗯,你不需要在几个地方使用它.我会这样解决这个问题:

  • 将XAML添加到视图中,而在.xaml.反恐精英
  • 在ViewModel中编写每个应用程序逻辑(除了可以直接使用UI元素的东西)
  • 所有应该由用户界面完成但与业务逻辑无关的代码都会进入到应用程序中.xaml.cs文件

我认为MVVM的目的主要是将应用程序的逻辑和具体的UI分离,从而使UI易于修改(或完全替换).
我使用以下原则:View可以从ViewModel知道和假定它想要的任何东西,但是ViewModel不能知道关于View的任何信息.
WPF提供了一个很好的绑定模型,您可以使用它来实现这一点.

(顺便说一句,如果使用得当,模板和lambda表达式并不深奥.但是如果你不想,就不要使用它们.)

让你盯着屏幕挠头的东西.

是的,我知道那种感觉.这正是我第一次看到MVVM时的感受.但一旦你掌握了窍门,你就不会再感到难受了.

我有一个盒子工作得很好...

为什么要在"关于"框后面放置ViewModel?这没有意义.

大多数MVVM工具包都掩盖了对话框,当它们处理对话框时,它们只是警告框,不需要自定义界面或视图模型.

Yes, because the very fact that a UI element is in the same window, or another window, or is orbitting Mars at the moment is none of the ViewModels' concern.
Separation of Concerns

EDIT:

这是一段很好的视频,标题是Build your own MVVM framework.值得一看.

.net相关问答推荐

安装特定主要版本的DotNet SDK最新版本

如何将 select 语句详细信息提取到不同的方法中仍然保持Eager 加载?

为什么脚本不从 _Layout 加载并且必须添加到部分视图中?

如何在 .net MAUI 中删除不需要编译的平台?

如何知道变量是否只是指向另一个对象的pointer或者它是否可以独立存在

无法加载文件或程序集 不支持操作. (来自 HRESULT 的异常:0x80131515)

Erlang 的让它崩溃的哲学 - 适用于其他地方吗?

.NET 应用程序的链接器状态(又名请先生,我可以有一个链接器2009 年版)

RNGCryptoServiceProvider 的优缺点

如何明智地使用 StringBuilder?

String 是原始类型吗?

清除 .NET 的 StringBuilder 内容的最佳方法

从 Windows 窗体打开 URL

WCF服务客户端:内容类型text/html;响应消息的charset=utf-8 与绑定的内容类型不匹配

.NET 事件 - 什么是对象发送者和 EventArgs e?

ILookup 接口与 IDictionary

风格上的差异:IDictionary vs Dictionary

从 'System.Int32' 到 'System.Nullable`1[[System.Int32, mscorlib]] 的无效转换

合并两个(或更多)PDF

忽略 LINQ to XML 中的命名空间