MVVM 模式能够帮你把你程序的业务与展现逻辑从用户界面干净地分离开保持程序逻辑与界面分离能够帮助解决很多开发以及设计问题能够使你的程序能更容易的测试维护与升级它也能很大程度的增加代码重用性并让开发者与界面设计者更容易地相互合作
使用 MVVM 模式程序的 UI 和其背后的展现与业务逻辑将被分离至三个类中
视图封装 UI 与 UI 逻辑
模型视图封装展示逻辑与状态
模型封装程序的业务逻辑以及数据
MVVM 模式是展示模型模式的变种它优化了一些 WPF 的核心特性例如数据绑定数据模版命令以及行为在 MVVM 模式中视图通过数据绑定以及命令行与视图模型交互并改变事件通知视图模型查询观察并协调模型更新转换校验以及聚合数据从而在视图显示
下图展示了 MVVM 类以及它们之间的交互
视图类
视图的责任便是定义用户在屏幕上能看到的一切的结构以及外观理想的视图背后的代码只包含调用 InitializeComponent 方法的构造函数视图通常扮演以下关键角色
视图是可视化元素例如窗口页面用户控件或者数据模版
视图定义了包含在视图里的控件以及可视化层以及样式
视图通过 DataContext 属性应用视图模型
绑定了控件以及数据的属性以及命令被视图模型暴露出来
视图可以定制化视图与视图模型间数据绑定行为
视图定义以及处理 UI 可视化行为例如动画
视图背后的代码实现了用 XAML 很难表达的可视化行为
视图模型类
视图模型在 MVVM 模式中为视图封装了展示逻辑它并不是直接引用视图或者任何其他关于视图特定的实现或者类型视图模型实现了属性以及命令使得视图进行数据绑定并通过改变事件通知来提醒视图状态已经改变了视图模型提供的属性和命令定义了提供给 UI 的功能但是视图定义了如何渲染的功能
视图模型负责协调视图与任何需要的模型类的交互很典型的视图模型与视图类有着一堆多的关系视图模型可以选择直接将模型类暴露给视图因此视图的控件能够直击进行数据绑定视图模型可以转换或者操纵模型数据所以能够很容易被视图使用
很典型的视图模型会定义能被展现在 UI 上并被用户调用的的命令或者行为一个通用的例子就是当视图模型需要提交命令时会允许用户提交数据到网络服务或者数据库视图可以选择用一个按钮来展示所以用户能够点击该按钮提交数据典型地当命令编程不可用的它相关的 UI 展示也变得不可用视图模型通常扮演下面这些关键角色
模型视图是非可视化类它封装了展现逻辑
视图模型是可以独立于视图与模型调试的
视图模型很典型地是不直接引用视图的
视图模型实现了视图用来数据绑定的属性与命令
视图模型通过改变提醒事件通知视图状态的改变INotifyPropertyChanged 与 INotifyCollectionChanged
视图模型协调视图与模型的交互
视图模型可以定义视图展现给用户的逻辑状态
模型类
model 在 MVVM 模式中封装了业务逻辑以及数据业务逻辑定义了像所有检索和程序数据管理相关的程序逻辑一样用来确保所有的保证数据持久与有效的业务规则被应用最大化代码重用模型不能包含任何特定的情况特定的用户任务以及程序逻辑
典型的有模型为程序展现了客户端域模型模型也可能包含支持数据访问与缓存的代码即使有一个分离的数据库或者服务被使用模型与数据房分层通常被作为数据访问或呜呜结构而生成例如 ADONET 尸体矿井唉WCF 数据服务或者 WCF RIA 服务
模型层实现了轻松绑定视图的功能这通常意味着它支持通过 INotifyPropertyChanged 与 INotifyCollectionChanged 进行属性与集合更改通告展现对象集合的模型类典型地源自 ObservableCollection<T>类该类提供了对 INotifyCollectionChanged 接口的实现
模型也能通过 IDataErrorInfo 接口支持数据验证以及错误报告这些接口允许当数值改变时的 WPF 数据绑定被通知从而更新界面模型通常扮演如下的关键角色
模型类是不可视类它封装了程序数据
模型类不直接应用视图或视图模型类
模型类不依赖于它们是如何实现的
模型类是典型地通过 INotifyPropertyChanged/INotifyCollectionChanged 接口提供属性与集合更改事件的
模型类很典型地继承自 ObservableCollection<T> 类
模型类是很典型地通过 IDataErrorInfo/INotifyDataErrorInfo提供数据验证与错误报告
模型类典型地与封装了数据访问的服务一起使用