没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
[译]WPF 应用法度和 MVVM 设计模式 ——Josh Smith
2011-10-31
应用 Spring 的 WebServiceProxyFactory 动态生成 WebService 代码,设备如下五卷书
真正的友情是竭诚的和大胆的。这篇文章评论辩论:
若是知道岁月的易逝而名贵爱护,不作无谓的伤感,并向着本身应做的事业去尽力,尤其是青年时代一点
也不把时候滥用,那我们可以果断地说将来必定是会成功的。模式与 WPF
MVP 模式
为什么 MVVM 加倍实用于 WPF
用 MVVM 构建一个应用法度
内容:
专业的软件用户界面开辟不太简单。它可能混淆了数据、交互设计、视觉设计、连接、多线程、安然
性、国际化、验证、单位测试以及可触摸技巧。推敲到用户界面露出了体系的底层并且必须满足用户的不
成预知的需求,它可能是很多应用法度中最不稳定的项目组。有一些常用的设计模式可以解决这个题目,
然则隔离并且接见这些存眷点可能斗劲难。模式越是错杂,更多的捷径可能会被用到,这些捷径垂垂的破
损了以前所有正确体式格式做工作的尽力。
不老是设计模式的题目。有时辰我们会用到错杂的设计模式,因为现有的 UI 平台不克不及供给一个
很好的设计模式,它须要写很多的代码。我们须要的是如许一种平台,它使得哄骗简单的、可以或许经受
时候考验的、并且能让开辟者接管的设计模式来构建 UI 变得简单。荣幸的是,WPF 很好的供给了这些。
因为软件界采取 WPF 的比率络续增长,WPF 团队已经开辟了它本身的模式生态体系和实践。在这篇
文章中,我将回顾一些很好的设计实践,并且用 WPF 实现一个应用法度客户端。哄骗 WPF 的一些核心
特点连络 MVVM 设计模式,我将介绍一个实例法度,它显现了哄骗正确的体式格式构建 WPF 法度是多么
简单。
在这篇文章的结尾,我们将用数据模板、号令、数据绑定、资料体系和 MVVM 模式连络在一路创建
一个简单、可测试的、简单的框架。哄骗这个框架,我们可以创建任何的 WPF 法度。此文章的示例法度
可以当做一个真实的 WPF 项目标模板,它应用 MVVM 作为核心架构。法度中的单位测试项目会告诉你测
试应用法度的 UI 功能是多么简单,这些功能存在于 ViewModel 类中。在进入细节之前,让我们起首回顾
一下为什么要用 MVVM 如许的模式。
有序与杂沓
在一个简单的“helloworld”法度里面应用设计模式是多余的,并且会拔苗助长。任何一个合格的开辟
人员能一目了然的懂得几行代码。 然而,当法度的功能增长时,代码行和组件的数量响应地也会增长。
最后,体系的错杂性和反复呈现的题目增长,这促使开辟者以一种易于懂得、评论辩论、扩大、故障打消
的的体式格式去组织代码。在源代码中,我们经由过程对实体的杰出定名来削减认知的杂沓。我们经由过
程推敲它在体系中的功能角色来断定实用于一段代码的名称。
开辟者经常经由过程设计模式特地的组织代码,而不是天然的应用它们。这两种体式格式都没有错,
然则在这篇文章里,我查核了在一个 WPF 应用法度中明白地应用 MVVM 作为架构的益处。这些类的名字
包含了 MVVM 设计模式中熟悉的条目。例如,以“ViewModel”结尾的类是 View 的抽象。这有助于削减避
免前面提到的认知的杂沓。你能很兴奋的把握这种杂沓,在很多专业的软件开辟项目中这是一个天然的状
况。
MVVM 的演变
自从人们开端创建软件的用户界面,就有一些常用的设计模式使它变得变得简单。例如,MVP 模式
在各类 UI 编程平台下大受迎接。MVP是 MVC 模式的变种,它已经存在了数十年了。若是你以前没有效
过 MVP 模式,这里做一个简单的申明。你在屏幕上看到的就是 VIew,它所显现的数据就是
Model,Presenter 连接这两者。View 依附于 Presenter哄骗 Model 的数据去填充它、对用户的输入做出
反响、供给输入验证以及一些其它的验证。若是你想要进修更多的 MVP,推荐你浏览 Jean-PaulBoodho
o的 August2006DesignPatternscolumn。在 2004 年,MartinFowler揭晓了关于 PresentationModel
(PM)模式的文章。PM模式在将 View 和他的状况和行动分别上方斗劲类似。PM 模式有趣的处所是发
了然名为 PresentationModel 的 View 的抽象。View 仅仅只是 PresentationModel 的发挥解析。遵守
Fowler 的申明,PresentationModel 频繁更新的是它的 View,以便这两者之间对峙一致。 同步的逻辑作
为代码存在于 PresnetationModel 类里。
在 2005 年,微软的 WPF 和 SL 架构师 JohnGossman 在他的博客中公开了 MVVM 模式。 MVVM 与
Fowler 的 PM 模式完全雷同,这两种模式都专注于 View 的抽象,它包含了 View 的状况和行动。Fowler
引入 PresentationModel 作为一种与 UI 平台无关的 View 的抽象的创建,而 Gossman 引入 MVVM 作为一
种哄骗 WPF 的核心特点去简化用户界面的创建的标准化的体式格式。 在这个以意义上看,MVVM 相对于
通用的 PM 加倍专一化,是为 WPF 和 Silverlight 平台而量身定做的。
GlennBlock 在 2008 年九月揭晓了这篇优良的文章:Prism:PatternsforBuildingCompositeApplica
tionswithWPF。他说了然针对于 WPF 的 MicrosoftCompositeApplicationGuidance。ViewModel还未
被用到。反而,PresentationModel被用来描述 View 的抽象。贯穿这篇文章,我将这种模式叫做
MVVM、View 的抽象叫做 ViewModel。我发明这个术语在 WPF 和 MVVM 社区加倍风行。
不像 MVP 的提出,ViewModel不须要 View 的引用。View 绑定到 ViewModel 中的一个属性。这个属
性显现了 Model 对象的数据以及 View 的其它状况特点。因为 ViewModel对象被设置为 View 的
DataContent,View 和 ViewModel 之间的绑定易于构建。若是 ViewModel里面的属性值改变了,那些新
的值会经由过程数据绑定传递到 View。当用户点击 View 的一个按钮,ViewModel里面的一个号令就会履
行完成须要的动作。ViewModel 而不是 View 履行了 Model 数据的批改。View 类不知道 Model 类的存在,
ViewModel和 Model 也不知道 View。实际上,Model 完全不知道 ViewModel 和 View 存在的事实。 这是
一种松耦合的设计,你将看到这种体式格式的益处。
为什么 WPF 开辟者喜好 MVVM
一旦开辟人员喜好上了 MVVM 和 WPF,就很难区分他们两者。MVVM是 WPF 开辟者的通用语,因
为他很是合适 WPF 平台,WPF 被设计使它很轻易应用 MVVM 模式去构建应用法度。实际上,微软内部
哄骗 MVVM 开辟应用法度,例如 ExpressionBlend,而核心 WPF 平台正在构建中。WPF 的很多方面,
例如 look-less 控件模型和数据模板,经由过程 MVVM 将显示和状况和行动分别。使得 MVVM 成为一种
优良的设计模式的最首要的一个方面就是数据绑定。经由过程将 View 的属性绑定到 ViewModel,可以在
这两者之间获得松耦合,完全地移除了在 ViewModel 里直接写代码更新一个 view 的须要。数据绑定体系
同时供给了输入验证,供给了一个标准的体式格式将验证错误传到 View。
WPF 的别的两个使得 MVVM 模式有效的特点的数据模板和资料体系。View 的数据模板将
ViewModel 的对象显示到用户界面。你可以在 Xaml 中定义模板,并且在运行时让资料体系主动查找和应
用这些模板。你可以在我的 2008 年 7 月的文章 DataandWPF:CustomizeDataDisplaywithDataBindin
gandWPF 中进修更多的数据绑定和数据模板。若是 WPF 不支撑 Commands,MVVM 将远没有如此强
大。在这篇文章中,我将告诉你 ViewModel 如何将 Commands 公开到 View,从而让 View 应用它的功能。
若是你对 Command 不熟悉,我推荐你浏览 BrianNoyes 在 2008 年 9 月的综合性的文章 AdvancedWPF:
UnderstandingRoutedEventsandCommandsinWPF。
除了 WPF(以及 Silverlight2)的特点使得 MVVM 天然处所式去构建应用法度,这个模式风行的也因
为 ViewModel 类轻易做单位测试。当一个法度的交互逻辑存在于一套 ViewModel 类中时,你可以很轻易
写出代码测试它。从某种意义上说看,Views和单位测试是 ViewModel的两种不合的花费者。应用法度
的 ViewModel 的一套测试法度供给了一个快速的回归测试,帮助削减法度保护的消费。
除了促进发明主动回归测试,ViewModel的可测试性有利于正确地设计易于换肤的用户界面。当你
设计一个应用法度的时辰,想象你须要你须要写一个单位测试来测试 ViewModel,如许你就熟悉打听一些
功能是该写在 View 里面还是 ViewModel 里面。若是你能为 Viewmodel 写单位测试而没有创建任何 UI 对
象,你也就能完全地剥离 ViewModel 因为它不依附于指定的可见元素。
最后,对于视觉设计的开辟人员,应用 MVVM 使得创建腻滑的设计者/开辟者工作流变得加倍简单。
因为 View 只是 ViewModel 的随便率性花费者,很轻易剥离 View 而换一个新的 View。这个简单的步调容
许我们进行快速的原型设计以及设计人员进行 UI 的评估。
开辟团队可以将重视力集中于结实的 ViewModel 类的创建。设计人员可以专注于创建用户友爱的
Views。连接这两个团队的输出除了确保 Xaml 里面的绑定存在可能设计更多。
演示法度
此刻,我已经查阅了 MVVM 的汗青和理论操纵。我查询拜访了为什么它在 WPF 开辟者中这么风行。
如今,我们看看这个模式是如何运作的。这篇文章的演示法度用多种体式格式来实现 MVVM。它供给了
雄厚的实例用以将概念融入实际的靠山中。我在 VisualStudio2008SP1,.NET 框架 3.5SP1 中创建这个
演示法度。单位测试运行在 VisualStudio 单位测试体系。
法度可能包含多个“工作区”,用户可以点击左边导航区域将它们打开。所有的“工作区”在首要内容区
域的 TabControl中显现。用户可以点击 Tab 项的封闭按钮来封闭一个工作区。应用法度有两个可用的工
作区:"AllCustomers"和"NewCustomer"。
运行法度并且打开一些工作区之后,界面如下:
图 1工作区
一次只能打开一个"AllCustomers"工作区,然则可以同时打开多个"NewCustomer"工作区。当用户
想创建一个新客户的时辰,他必须填写图 2的表格数据。
图 2用户填写数据表格
当用户填写有效的数据,并且点击 Save 按钮的后,新的用户名字呈如今标签项中并且这个用户被添
加在 Allcustomers 中。此法度不支撑编辑和删除已存在的用户,然则此功能以及其它很多类似的功能在
建树好应用法度框架之后是很轻易实现的。如今你已经很好的懂得了这个示例法度所作的,让我们研究它
是如何设计与实现的吧!
RelayingCommand逻辑
除了类机关函数里面的 InitializeComponent生成的标准模板代码,法度的每一个 View 都有一个
codebehind文件。实际上,你可以从中移除掉 view 的 codebehind文件,应用法度将仍然能正确地编译
和运行。 尽管 View 中没有事务处理惩罚办法,当用户点击按钮的时辰,法度仍然可以或许响应用户的恳
求。这是因为绑定建树在 UI 控件,例如超链接,按钮和菜单项控件上的 Command 属性上。绑定使得
用户在控件上点击的时辰,ViewModel的 ICommand 对象被履行。你可以把 command 对象作为一个适
配器,它使得从 XAML 中声明的视图中调用 ViewModel 的功能变得简单。当 ViewModel 显现了
ICommand 的一个实例时,Command 对象经由过程 ViewModel 去完成它的工作。一种可行的实
现模式是在 ViewModel 类中创建一个私有的嵌套类,一遍 Command 可以应用 ViewModel 类中的
私有成员。并且不会污染到定名空间。这个嵌套类实现了 ICommand 接口,并且将 ViewModel 的一
个应用注入到它的一个机关函数中。然而为每一个实现了 ICommand 接口的 Command 创建嵌套类
可能使得 ViewModel 类变得膨胀,越多的代码意味着越多的 Bug 存在的可能性。
在本法度中,RelayCommand类解决了这个题目。RelayCommand容许你经由过程注入 Command
的逻辑到机关函数中。这种办法容许在 ViewModel 类中以简洁的,简明的号令实现。RelayCommand
是 MicrosoftCompositeApplicationLibrary 种中 DelegateCommand的简化。图 3显现了
RelayCommand类:
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute)
:this(execute,null)
{
}
public RelayCommand(Action<object> execute,
Predicate<object> canute)
{
if (execute== null)
throw new ArgumentNullException("execute");
_execute= execute;
_canute= canute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool Canute(object parameter)
{
剩余24页未读,继续阅读
资源评论
- 曾海波2013-03-07文档写的很详细
- 小__朋2013-04-19内容详细,适合新手。
liujiancheng815
- 粉丝: 3
- 资源: 12
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功