WPF中模型-视图-视图模型模式介绍

来源:互联网 发布:java web后端开发 编辑:程序博客网 时间:2024/06/03 08:45

在目前开发中,流行的开发模式有MVC(模型-视图-控制器)和MVP(模型-视图-表示器),其中MVC模式常见于java web开发中,比如Struts2、Struts2,后来微软也推出了MVC模式的开发框架。MVP模式是从MVC演变过来的,作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从直接Model中读取数据而不是通过 Controller。但是,如果把它们都用在与WPF中,存在着一个重要的缺陷:根本没有考虑数据绑定技术。也就是说,在这些模式中,控制器或者表示器负责作用与视图,如在文本库填写文字,加载列表框,填充网格。而WPF最大的优点在于它丰富的数据绑定能力。如果在WPF中利用MVC或者MVP,则完全忽略了WPF中数据绑定的便利性。

有没有一种方法可以从模型中分离视图,而不用忽略大WPF的特性呢,答案就是采用模型-视图-视图模型模式。这个模式是在John Gossman博客中看到的,他以前是Microsoft Expression Blend团队的成员之一,现在在Microsoft的WPF团队。模型-视图-视图模型模式把模型从视图分离,但同时充分利用WPF的特性。该模式采用纯粹的模型,创建一个包含状态的抽象视图,用可视化设计器创建一个视图,将其数据绑定到抽象视图。其中可视化设计器可以是Microsoft Expression Blend工具,抽象视图就是视图模型。视图和视图模型之间通过数据绑定建立双向连接。经过适当的设置,每一个视图只包含纯粹的XAML以及非常少量的过程代码,这样UI美工就可以专注于设计视图,而不必担心对开发有任何的影响。

在这里,还要介绍下视图模型这个概念。视图模型存在的目的就是把模型适配到视图。这就意味着在模型中有一个方法,该方法返回一个特性的类型,比如IList<T>类型,然后视图把来自模型的类型转换为类似WPF UI元素的CollectionView类来帮顶数据。此外,因为WPF自然的实现了命令(Command)模式,也就是说某个UI元素,比如按钮,它有一个属性为Command,是WPF定义的ICommand类型。于是,我们可以把命令放进视图模型中,并作为公有属性提供,以便视图绑定。这将非常有用,因为它允许把可执行代码绑定到表单上的按钮,而不用编写任何代码来连接按钮。WPF的命令模式以及视图模型的公有Command属性负责上述工作。

讲了那么多,下面通过实例来实践下。

一、建立一个模型类,命名为ProjectService,该类中提供了一个供视图模型类方法的方法GetAllProject,代码如下:

 

这段代码很简洁,功能非常的简单,仅仅是提供一个集合给视图

二、构建一个视图,主要是在界面中已下拉表的形式向用户显示列表。为此,需要构建一个响应的视图模型类,这样就可以让视图类来绑定它。所以在这里定义了一个视图模型类ProjectViewModel,该类提供一个列表和两个命令:

 

在ProjectViewModel中,用到了IView类型,它是一个接口。主要是提供一个视图的引用,在这里,我们在IView中定义了两个方法,Show方法和Close方法。而且WPF Window类碰巧也实现了这两个方法:

 

然后ProjectViewModel要做的另外一件事就是把IList<Project>列表的项目转换成WPF的CollectionView类,所以在视图模型类中提供了Projects公有属性给视图。接下来的两个DelegateCommand 属性,用于视图类中的按钮设置ICommand性,DelegateCommand 不仅实现了ICommand接口,而且还允许调用ICommand的Execute方法时,调用一个委托,DelegateCommand 的代码如下:

 

 

到现在为止,已经接到了视图模型类,下面将讲述视图实际上如果使用它并和它通讯,视图类ProjectView的隐藏代码很少,唯一为它编写的代码就是在构造器中用来连接表达的Window元素的DataContext属性:

 

注意,ProjectView实现了IView接口的Show、Close方法。然后在ProjectView视图的XAML中编写显示到UI'的代码:

 

 

这样一来,一个模型-视图-视图模型表示模式的实例就出来了,通过这个实例,我们可以很明了的看到。UI设计与后台代码之间的关联就没有那么强了,界面设计与开发独立开来。

原创粉丝点击