译:Introduction to Model/View/ViewModel pattern for building WPF apps

原文背景

相对于 MVC 的历史来说,MVVM 是一个相当新的架构,MVVM 最早于 2005 年被微软的 WPF 和 Silverlight 的架构师 John Gossman 提出,并且应用在微软的软件开发中。该篇译文的原文即为John Gossman当年发布的博文。

翻译这篇文章,是期望在当今普遍地对MVX(该文主要说MVVM)相关模式片面理解的大环境下,让大家可以基于MVX最初提出,对我们对与MVX的实践应用以及MVX的本源思路进行一些思考。

文章关键技术名词简析

WPF :Windows Presentation Foundation,是微软推出的基于Windows 的用户界面框架,属于.NET Framework 3.0的一部分。

MVC :Model/View/Controller,模型/视图/控制器开发模式。

MVVM : Model/View/ViewModel,模型/视图/视图模型开发模式,是MVC的一个变种模式。

HTML :HyperText Markup Language,超文本标记语言,我们查看的网页的基础语言就是它。

XAML :eXtensible Application Markup Language,可扩展应用程序标记语言,是微软公司为构建应用程序用户界面而创建的一种新的描述性语言。

WYSIWYG :What You See Is What You Got,所见即所得,比如你在用美图秀秀处理图片的时候,图片处理完成展示的样子就是它最终的样子。(而不像用代码写视图一样,从代码中,外行人完全不知道最终展示的视图的样子)。

Dreamweaver :一款“所见即所得”的网页编辑器。

Flash : 一款“所见即所得”的动画编辑器。

Sparkle :另一款“所见即所得”的网页设计工具。

Smalltalk :公认的历史上第二个面向对象的程序设计语言(第一个是Simula 67)和第一个真正的集成开发环境 (IDE)。

Avalon :一个简单迷你的MVVM框架。

关系表 :原文中是relational tables,个人感觉理解为关系型数据库的数据表就没什么大问题了。

XML :eXtensible Markup Language,可扩展标记语言,经常用来描述进行通信的数据结构。(类似Json)

GUI :Graphical User Interface,图形用户界面。

触发器 :trigger,SQL server 提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程。它的执行不是由程序调用,也不是手工启动,而是由事件来触发。

单向绑定 :基于本文,是模型和视图的绑定,可以理解为模型数据变化触发视图更新。

双向绑定 :基于本文,是模型和视图的绑定,可以理解为模型数据变化触发视图更新,且视图操作触发模型数据更新。

bool :一个数据类型,其取值只能为0或1。

TextBox :文本框(翻译不需要太纠结)。

CheckBox,选择框,就是那个你在注册账号时候,注册协议旁边可以点击打钩的那种控件。(如图)

image.png

UI,User Interface,用户界面。

Assembly :.Net中反射机制的一个类封装。相关的数据结构有如下几个:AppDomain(应用程序域),Assembly(程序集类),Module(模块类),Type(使用反射得到的类型信息的最核心类)。它们之间的关系是:AppDomain包含多个Assembly,Assembly包含多个Module,Module包含多个Type。Assembly是有一个name属性的,该文中,举例的工程直接使用了Assembly数据结构。

ComboBox :下拉选框,点击了下拉框会弹出选择菜单的那种。(如图)

image.png

ListBox :列表,本文中的话,还是能滚的那种。(如图)

image.png

Library/Appearance/Project :文中直接对应举出的例子对应的三个面板,无需特别翻译。

MSBuild :Microsoft Build Engine 的缩写,基于该文,MSBuild Project的模型理解为一个已存在的,且不方便修改其属性定义的模型就够了。

译文正文

使用MVVM模式搭建WPF应用的方法介绍

MVVM是MVC模式的一个演变,针对一个视图的展示样式,比起传统的开发者,现在往往是设计师更为关注,MVVM正是为这种状况而定制的一种模式。一个设计师,往往更关注图形、艺术的呈现效果(传统的开发者则不会),他们常常使用声明式语言(如HTML,XAML)和WYSIWYG工具(所见即所得编辑器,如Dreamweaver,Flash,Sparkle)。简单地说,不同于后端逻辑或者后台数据,一个应用的UI部分常常会被不同的人使用各种各样的开发工具,各种各样的开发语言来完成开发。从MVC到MVVM促使了从Smalltalk到Web/Avalon这样一个转变,前者(smalltalk)只使用一种语言一套环境来开发一款应用,后者则为我们更为熟知的现代开发模式。
讨论MVVM,你还需要了解“数据绑定机制”,下文中我们详细说明。

MVC中的Model,被定义为完全独立于UI的数据或业务逻辑。模型常常用代码编写或者使用关系表/XML这样的纯数据表示。

MVC中的View,由按钮,窗口,图标和其它复杂的GUI控件这些可见的元素组成。View约定了一些快捷操作接口,它们接受MVC中Controller所需要管理的输入设备传递的信息,并使视图本身做出相应的响应。(研究当代GUI开发中Controller中发生的种种就有些严重跑题了……我更倾向于把它当做一个背景话题。我们没必要像在1979年时那样去探讨它)视图常常通过一些工具以“描述”的方式定义。介于这些工具和描述式语言的特性,MVC在View类中存储的视图状态信息将极难展示。举例来说,一个UI视图可能有不同模式的交互方式,比如“视图模式”和“编辑模式”(可以改变控件行为,改变可见元素样式),但这些模式信息常常是无法在XAML中进行描述的(虽然触发器是个不错的开始)。我们马上来解决这个问题。

我们该谈到数据绑定了。举一个简单的例子,视图和模型进行直接的绑定。一部分只供展示的模型字段进行单项绑定,另一部分可以被修改的模型字段进行双向绑定。举例来说,一个模型中bool值可以转化成字符绑定到一个TextBox(单向),也可以直接绑定到一个CheckBox(双向)。

然而通常,只有很小部门的UI元素可以直接和数据模型进行绑定,尤其在模型是开发者无法掌控的已经定义好的类或数据模板的时候,模型常常会存在一些无法直接和控件进行映射的的数据类型。UI的某些复杂操作是必须通过代码实现的,而这些代码,难以被视图所“理解”(即放到视图中不合适),但放到模型中又太特别了(或者这些逻辑没有被已存在的模型类所包含)。所以,我们需要一个存放诸如选择状态,模式信息的地方。

ViewModel就是为了完成这些任务而存在的。它意为“视图的模型”,提供模型与视图进行数据绑定的特殊支持,当然,比起模型,它更像视图。针对ViewModel提供否认数据绑定支持,它将包括将模型类型转化为视图类型的数据转化功能,以及操作那些可以被模型影响的视图。

我会在以后的文章中深入讨论如上观点,尤其说明怎样在ViewModel中实现命令绑定。但快速阐明这个模式,我们还是看一看下面的例子吧!

image.png

上面的图片展示了Sparkle(一款WebUI搭建工具)UI界面中的三个编辑面板。每一个面板都是使用MVVM模式开发的。最简单的是位于顶部的Library面板。它的模型是一个Assembly的列表(即每项都是System.Reflection.Assembly的一个实例),Assembly中的每一个列表又分别和一个控件列表建立关联。该视图由一个面板控件,一组控件样式和一个数据模板组成,该数据模板由一个展示Assembly列表的ComboBox(下拉选框)和一个可以展示控件列表的ListBox组成。我们把ComboBox的标题和Assembly的标题直接关联,而ListBox的中的每个项目,它们的名字即为它们所代表的控件的名称。ViewModel保存当前选择的Assembly,并执行了将相关控件进行展示的命令。选择是视图模型最常见的功能之一。但当我们将选择功能封装在控件当中,你会想问“为什么不将选择功能放在存放在视图(控件的父视图)当中呢?”这是因为视图中的多个控件的选择功能是有协作逻辑的。比起在视图中处理所有不同控件的协作关系,讲一个控件的选择展示控制和ViewModel进行绑定显然是更简单的方式(然后控件的选择协作逻辑在VM中处理)。基于如上设计,在Library面板中,(VM中)选择的Assembly同时决定了ComboBox和ListBox的展示内容。而且,设计者可以在不拷贝选择协作逻辑代码的情况下,轻松地修改原来的视图设计,比如使用ListBox来展示Assembly列表,用ComboBox来展示控件列表。

Appearance面板的模型中保存了在Sparkle的编辑区域中选中的形状或控件。视图上,我们看到一个展示我们选择的属性(一般是关于画笔或刷子的)的ListBox。那些按钮决定了我们的刷子或画笔是纯色的或渐变色的。色谱视图则用来编辑颜色组成。VM中保存的信息包括“被选择的属性”,“渐变色的边缘色信息”,“将颜色转换成文本描述或色谱图上坐标信息的数据转化方法”,“当画笔,刷子样式改变时发出的控制命令”。这个场景中,我们直接使用了Avalon框架提供的模型,视图可以轻易地完成巨大的变化,而VM则从UI的重用部分中提取展示的抽象。

最后一个例子是Project面板。这边的模型是属于一个MSBuild工程……而且,一个模型类是已经存在的。视图是一个树形控件,可以滚动,而且包含了详情菜单。ViewModel兼容了MSBuild的不考虑Avalon框架概念的设计模式(即通过命令行即可进行完美的工作)的问题,这样我们就可以对它们进行数据绑定,然后添加选项和命令了。

一旦你使用了MVVM模式,任何UI的问题都可以被快速处理。事实上,整个Sparkle的UI都是通过这种模式实现的。“在编辑区域选择形状或控件” 的展示面板的模型,其本身也是我们场景编辑器的一个ViewModel。Sparkle中面板的布局中,包含一个所有注册的面板的列表模型,一个由栅格为基础包含能定位视图的分割线的视图,还有一个VM,它保存了当前可见的面板和他们所应处的逻辑区域(比如编辑面板,右边,左边,底部)

今天就这样了……

原文链接

https://blogs.msdn.microsoft.com/johngossman/2005/10/08/introduction-to-modelviewviewmodel-pattern-for-building-wpf-apps/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容