65.9K
CodeProject 正在变化。 阅读更多。
Home

WPF:如果 Carlsberg 做了 MVVM 框架,第一部分(共 n 部分)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.76/5 (79投票s)

2009年7月11日

CPOL

9分钟阅读

viewsIcon

288240

它可能类似于 Cinch,一个用于 WPF 的 MVVM 框架。

目录

引言

距离我写一篇长文已经有一段时间了,所以我想是时候纠正一下,写一篇相当有分量的文章。本文及后续系列文章代表了这份分量。本文是即将发布的关于如何在 WPF 中做好 MVVM 的系列文章的第一篇。

对于那些不知道 MVVM 是什么的人来说,它基本上是一种 UI 设计模式,由于 WPF 提供的绑定选项,它特别适合与 WPF 一起使用。其理念是 ViewModel 是 View 的抽象,您应该能够通过运行系统内 ViewModel 的单元测试来实际测试整个 UI。事实上,我曾听一位非常有影响力的微软员工说过,在他们看到 UI 之前,他们想先看到单元测试,以了解一切是如何工作的。如果您能通过阅读单元测试来理解 UI 是如何工作的,那么您就正确地使用了 MVVM。

如果您需要,这里有一些不错的 MVVM 链接

在我看来,MVVM 是一种绝佳的模式,但它也有一些做得不好的地方,例如,如何从一个本质上不是 UI 的类中显示 MessageBox(模态对话框)?在弄清楚如何从 ViewModel 显示 MessageBox 之后,我们如何确保依赖于用户选择“是”或“否”以使 ViewModel 走特定代码路径的代码,能够在应用于 ViewModel 的单元测试中得到充分测试?这类事情并非易事。我见过数百篇声称是优秀的 MVVM 示例的文章,您知道吗,它们不是。它们展示了基本的绑定,而没有丝毫考虑到我刚才提到的这类问题。地球上可能只有 100 人正确地使用 MVVM,而我认识其中不少人。直到通过反复犯错的经历将信息灌输到您的脑海中,否则这并不容易。我现在觉得我犯错的次数已经足够多,可以有一定权威地谈论如何正确地做,以及如何避免做错。这就是所谓的实战检验。

我自己已经使用 WPF/MVVM 有一段时间了,并且在大部分时间里都在为这种所谓的优秀模式而苦苦挣扎,直到现在我才觉得“啊,我明白了如何 100% 正确地做到这一点。”本文及后续文章将与您分享这些知识。如果您想要这些知识。这取决于您。

那么,本文及后续文章到底是什么呢?简单来说,这是一个我称之为“Cinch”的 MVVM 框架,以及一个演示应用程序和一系列单元测试。虽然这听起来可能不太吸引人,但我希望随着我们在这个系列中深入,您会觉得“啊哈,这有点不错/很棒”,并且解决了我们遇到的所有难题,并且我看到了如何解决这些问题。即使您最终不使用 Cinch,您也可能会发现它的一些代码能在您的工作中有所帮助。那也很棒。

一件非常棒的事情是,整个演示应用程序的代码后台只有一行代码,这意味着我可以从单元测试中测试一切,是的,一切,线程、导航、视图/视图模型之间的消息、文件保存、文件加载等等。考虑到有 4 个视图和一个弹出窗口都在相互交互,这 1 行代码也不算差。

我希望您能从这一切以及后续文章内容中看到 Cinch 的优势。

这大概就是计划。

特别感谢

在开始之前,我特别要向以下各位表示衷心的感谢,没有他们,本文及后续系列文章将永远不可能完成。基本上,我对 Cinch 的工作就是研究了其中大部分人的成果,看看哪些是好的,哪些是坏的,然后提出了 Cinch,我希望它能解决其他框架未涵盖的一些新问题。

Mark Smith (Julmar Technology),感谢他出色的 MVVM Helper Library,它极大地帮助了我。Mark,我知道我征得了您使用部分代码的许可,您非常慷慨地同意了,但我只想对您精彩的想法再次表示衷心感谢,其中一些想法我确实从未想到过。我向您致敬,伙计。

Josh Smith / Marlon Grech(作为一个整体)感谢他们出色的 Mediator 实现。你们太棒了,一直都很愉快。

Karl Shifflett / Jaime Rodriguez(微软的员工)感谢他们出色的 MVVM Lob 之旅,我参加了,干得好,小伙子们。

Bill Kempf,感谢他成为 Bill,并是一位疯狂的向导般的程序员,他还拥有一个很棒的 MVVM 框架,名为 Onyx,我曾写过一篇关于它的 文章。Bill 总是能回答棘手问题的答案,谢谢 Bill。

所有 WPF Disciples 的成员,对我来说,这是最棒的在线社群。

谢谢你们,伙计/女孩,你们懂的。

本文有点特别!

从很多方面来看,本文绝对是一派胡言,因为它没有任何代码,也没有任何解释,但它将作为系列文章中即将到来内容的路线图……这基本上就是本文的全部内容,但我只是觉得有必要以某种方式解释其他文章。

我真的绞尽脑汁想如何最好地呈现这些内容,因为有很多(真的很多)内容需要消化,但最终我做出了这个决定,发布一篇入门文章,其中包含所有想要自己摸索的人的完整源代码,但没有任何解释。入门文章(本文)将仅仅作为进入真正核心内容的垫脚石,即下一篇文章。

这样,如果有人想查看代码,他们就可以查看,我唯一的要求是,如果人们现在就开始研究代码,能否请将复杂的问题留到本系列的后面?因为我将在本系列的后续文章中详细介绍所有内容。所以您将获得所有知识/内容,只是不是在这篇文章中,还不是现在。我将尽最大努力尽快发布内容。我希望下周就能发布另一篇文章。

必备组件

演示应用程序使用了

  • VS2008 SP1
  • .NET 3.5 SP1
  • SQL Server(请参阅 MVVM.DataAccess 项目中的 README.txt 文件,了解如何设置演示应用程序数据库)

本文将涵盖哪些内容?

实际上不多,我可以告诉你 Cinch 的功能,如下所示:

  • 允许视图将生命周期事件通信给 ViewModel,而无需维护任何硬引用链接,并且没有 IView 接口要求。视图和 ViewModel 之间没有任何关联。
  • 具有多种附加行为,用于常见任务,例如:
    • 数字文本输入
    • 基于 XAML FrameworkElement 的 RoutedEvent 在 ViewModel 中运行 ICommand
    • 为单个 XAML FrameworkElement 具有一组此类 ICommand/RoutedEvent 事件
  • 允许 ViewModel 确定 Model 的数据是否可编辑,UI 会通过绑定自动更新,基于 ViewModel 驱动的可编辑状态。这适用于单个 Model 字段级别,因此非常灵活。
  • 委托验证规则,允许验证规则尽可能细粒度
  • 使用委托规则方法进行原生 IDataErrorInfo 支持
  • 使用 IEditableObject 在编辑/取消编辑时存储/恢复对象状态
  • 弱事件创建,用于创建 WeakEvents
  • 弱事件订阅,也允许自动取消订阅
  • Mediator 消息传递,开箱即用支持 WeakReference
  • 使用 Unity DI 容器进行 DI/IOC,允许替代的测试/实际应用程序服务实现
  • 服务实现包括(Cinch 为 WPF/UnitTest 大多数服务提供了默认值,但弹出窗口服务除外,该服务将在后续文章中介绍,并且无论如何都会在附加的演示代码中可用):
    • 使用 Log4Net 进行高级日志记录 
    • MessageBox 服务(可以在单元测试中 100% 模拟,就像用户实际点击了 MessageBox 按钮一样),从而使 ViewModel 代码能够沿正确的路径遍历
    • 打开文件服务(可以在单元测试中 100% 模拟,就像用户实际在 Model OpenFileDialog 中选择了一个要打开的文件一样),从而使 ViewModel 代码能够沿正确的路径遍历
    • 保存文件服务(可以在单元测试中 100% 模拟,就像用户实际在 Model SaveFileDialog 中选择了一个要保存的文件一样),从而使 ViewModel 代码能够沿正确的路径遍历
    • 弹出窗口服务,用于控制 WPF 中弹出窗口的显示/隐藏和设置(这是一个噩梦)
  • 线程助手
    • Dispatcher 扩展方法,允许将 Action<T> 快速 marshaling 到正确的 UI Dispatcher
    • Application.DoEvents
    • Application.DoEvents(用于特定的 Dispatcher 优先级)
    • BackgroundTaskManager,带有回调,用于向等待的单元测试发出完成警报,以便测试可以完成或超时
    • ObservableCollection,在正确的 Dispatcher 线程上通知 CollectionChanged
    • ObservableCollection,允许添加一系列项目
  • 轻松实现MenuItem ICommand ViewModel
  • 可关闭的 ViewModel(在选项卡式 UI 环境中工作时,这实际上是使用 MVVM 应该做的事情)

即将推出什么?

在后续文章中,我将大致如下展示:

  1. Cinch 及其内部机制详解 - 第一部分
  2. Cinch 及其内部机制详解 - 第二部分
  3. 如何使用 Cinch 开发 ViewModel
  4. 如何使用 Cinch 应用程序对 ViewModel 进行单元测试,包括如何测试可能在 Cinch ViewModel 中运行的后台工作线程
  5. 一个使用 Cinch 的演示应用程序

我现在只想说这么多,但我可以向您保证,后续文章中将会有大量关于如何开始使用 Cinch 的内容和示例。

在此之前,如果您愿意,可以尝试/探索附件中的代码。如果您有特定疑问,能否请等到所有 4 部分都可用后再问?如果我还没有涵盖您想问的内容,请随时提问。

谢谢。

一如既往,欢迎投票/评论。

© . All rights reserved.