沈 浩翔 发表于 七 21, 2010
深入控件创新[2] – 初探控件
以下内容来自沈浩翔,由沈浩翔撰写完成,沈浩翔校对。并同步发布于沈浩翔个人博客。
版权声明:文章版权归原作者和求是设计会共同拥有,转载时请以超链接形式标明文章原始出处和作者信息。
开始之前
内容级别:中级
本文主要内容:本文是这次旅途的第二站。简单介绍一些常规的控件模式,对其进行简单解剖,将我们的思考从静态转向动态。
本文适用对象:交互设计师、产品设计师、前端开发工程师。
预备知识:
- 必要知识:使用过Jquery、YUI等JavaScript库,有接触过JavaScript,听说过服务器端控件、浏览器端控件,知道AJAX,听说过DOM和BOM,听说过MVC。
- 提升知识:熟悉MVC更佳,玩过ActionScript更佳,听说过ORM更佳,接触过WPF和Silverlight更佳,了解面向对象编程的思想更加。
关于更多知识:短短一篇文章,肯定无法将我想分享的所有内容传达出来,仅是抛砖引玉。
- 如果对文中提到的很多概念有很多疑问,欢迎大家留言,或Email:qiushid@gmail.com,我们会尽力给出让人满意的答复。
- 如果对本文中提到的很多内容,还不能理解,请积极查阅文末给出的参考资料,或自己主动学习,一定会给你带来巨大的帮助。
内容目录
- 引子-我们的愿望
- 用户体验设计模式(UX Pattern)和库(Library)
- 控件分类
- 控件构成
- 控件的数据、结构、表现、行为相分离
- 参考资料
引子-我们的愿望
不知道有多少设计师像我一样,为了将自己的想法自己的作品更好的表达出来,就想去学Flash,从更多的角度去展示产品不同的样子。
不知道有多少设计师像我一样,对那些酷炫的不得了的界面羡慕的一塌糊涂,然后就梦想自己的个人站点也要弄的那么酷,那么炫,这样才能自信的告诉别人——我是一个设计师!
不知道有多少设计师像我一样,在网上搜索各种Demo,各种效果,进行组装,进行拼贴,但又总是发现总是不尽如人意。
三年前的一个下午,因为要合作一个项目,我认识了冬至(求是会的四位发起人之一),我窝在他的寝室里讨论那个项目怎么实施,应该用什么样的方法。当时我们也在讨论我们未来应该走向什么样的方向,大三的我,已经决定开始向界面设计方向发展。当时,我整天看的是很酷很炫的界面,从冬至口中,我听说了交互设计,也知道了用户体验这个行业。
我怀揣着能完美的表达出自己的想法的梦想,一路走来,却始终无法释怀。拖拽控件,拼凑别人做出的零件,越来越让我难以忍受。
不知道又有没有人像我一样,在绘制界面效果时,在绘制线框图时,在撰写产品设计文档时,在产品策划时,怀疑自己是否还是个设计师。我想要做的设计,不仅仅是这样。
带着怀疑和梦想,我们终于该走进控件的世界了。
用户体验设计模式(UX Pattern)和库(Library):

可能很多人都看过《Designing Interface》这本书,并且获益良多。我也觉得这是一本非常好的工具书,通俗易懂,也非常适合给自己的知识结构打底。这应该算是一个UX设计师的必读书目。
这本书应该属于一本入门书,所以它将很多内容都放在了一起,比如第一章讲用户需求,第二章主要讲内容组织(这里必须要提一下,内容组织是信息架构的一个重要方面,这一章也可以说是信息架构的一些方式,但全书并不是在讲信息架构的模式。看到网上有人照着这本书写总结,把后面几章的内容也说成是信息架构的模式,真是让人心寒。),第三章讲的是导航,第四章讲的是布局,真正讲到控件方面内容的是第五到第八章。
这本书更多的是从设计表达方面,做出的归纳和总结。这本书里的分类主要是从设计表达的角度考虑。它可以指引我们如何选择合适的控件,但不能指引我们如何在这个程度上,进行创新,进行拓展,我们必须要走的更深。
其实只说是设计模式是不合适的,这个范围太宽泛了。网上的设计师们平时谈到的设计模式,其实应该算是界面设计模式,至多到用户体验设计模式。这里会有很多资源,过去有:
- Designing Interfaces
- Patterns in Interaction Design (Welie.com)
- UI Design Pattern Library
- Yahoo! Design Pattern Library
而去年Infragistics公司又上线了Quince。在每个模式中,还给出相关控件资源的链接,有的有开放的代码包下载。

《Designing Interfaces》是界面设计师兼软件工程师Jenifer Tidwell写的(设计和开发可以一条龙哦)。而Quince的后台则更强大。Infragistics是一家专门为各个平台开发控件库的公司,特别是为微软。Infragistics不仅为软件,也为web开发控件(到了这个水准,就能称作,啥平台,啥语言都不要紧,关键是思想了)。如果接触过大型应用的开发的话,应该对这家公司不陌生。很多大型应用的复杂控件都向他们定制.

在我们平时的应用开发中,大多数项目都只是拖库中的控件而已,不管是JQuery也好,YUI也好,或者拖动.Net的控件库也好。这是大部分软件和在线应用体验糟糕的原因。而交互设计师因为不了解控件实现的原理,往往知道哪里有问题,却不知道如何去修改控件,甚至在向前端开发表达时也表达不清楚。而假如前端开发对所使用的库不熟悉时,很多细节上的修改,他们也是做不到的。
有的开发者会推荐新人不要用DreamWeaver、VisualStudio等软件进行开发,说手写代码才是更健康的方式。其实其主要原因就是要避免拖控件的陋习,好的开发人员的所见即所得(WYSIWYG),不是看可视化界面进行修改,而应该是阅过控件无数,心中自然有码~
模式虽好,虽然可以大量减少工作量,但是我们仍旧需要根据需求,在已有模式上进行二次设计,在已有库的资源上进行二次开发。为了这个二次开发的实现,我们才有必要深入了解控件,了解那些基础的知识。
控件分类
微软WPF的控件分类
我选择WPF的控件分类来讲,主要有三个原因:
- 微软向来给人以笨重,面面俱到的印象,它的产品也的确有面面俱到这样的特征。WPF是微软的下一代技术(就市场竞争来说)。这里包含了微软对未来的见解。
- WPF摆脱了早期WinForm时代的弊端,分离比较彻底,在WPF平台下,一样可以很好的实现Ajax,和现代的主流的思想还是一致的。它具有面向对象的各种思想在里面,并且带有面向切面的前瞻。
- 我对WPF比较熟悉。
首先,微软将控件分了几个大类:内容容器控件(Content Container),界面元素容器控件(UIElement Container),文本输入控件(Text Input),文本元素控件(Text Element),多媒体控件。此外还有装饰器(Decorator和Adorner),Adorner是每个控件都会有的一个层面,类似于Flash按钮中的感应区域层,Decorator就是我在上一篇中提到过的RadioButton前面的选择圈啦这些的。
其中我们最需要关心的是内容容器控件和界面元素容器控件。上一篇中,我们提到静态界面和布局,主要相关的实际上是界面元素容器(即面板),和一些文本元素控件。这类控件,除了在布局时,缩放窗口时,有动态自适应之外,基本与动态的概念无关。微软设计的面板类控件[UIElement Container (Panel Class, Arrage UIElement, Content Property is Children) ]有:
- Canvas(画布)
- DockPanel (停靠板)
- Grid(窗格,和Html中的Table类似)
- TabPanel (标签面板)
- ToolBarOverflowPanel (工具条内容超出面板)
- ToolBarPanel (工具条面板)
- UniformGrid (等分窗格)
- StackPanel (堆栈面板)
- VirtualizingPanel (虚拟化面板)
- VirtualizingStackPanel (虚拟化堆栈面板)
- WrapPanel(滚卷面板)
微软将面板分类的很细(相对于HTML来说),但仍然是不能包含所有面板的,比如像以前的框架(Frame)一样的面板(可以拖动框架间的边框,伸索不同部分的大小)。
在我们今天这篇初探控件时,我们最应该关心的,应该是内容容器控件。下面这张表是微软根据控件内容模型,对内容容器控件进行的分类。它首先分为了四大抽象类(关于抽象啊、继承啊这些的,属于面向对象编程概念,下一篇中会提到,文末会有推荐阅读资源):内容控件、头内容控件(继承自内容控件)、选项控件、头选项控件(继承自选项控件)。

|
ContentControl |
HeaderedContentControl |
ItemsControl |
HeaderedItemsControl |
|
|
|
|
这里的控件也并不是穷尽了所有控件,比如手风琴面板(Accordion,也有的叫OutlookBar),比如GridView,比如Ribbon(微软Office2007的菜单),比如日历(Calender),等等等等。微软只是提供了非常常用的一些控件而已。并且微软认为,在WPF体系下,通过微软提供的一些方式,主要是依赖项属性(Dependency Property)和控件自定义等等的方法,完全可以扩充出其他复杂控件了。
从而在使用WPF控件(其实使用任何控件都是这样)时,我们需要做的无非两类工作:
- 第一类是覆盖原有控件结构和属性;
- 第二类是组合自定义控件。
从这个控件的两层分类中,我们已经可以看出控件分类上的层级结构。因为在实现时,每个控件,每个XAML元素,实际上都是一个类(Class)。类具有继承关系,这是XAML比HTML复杂的地方,这也是动态的控件比静态的布局复杂的地方。在我刚接触XAML的时候,我一直带着HTML的思维,我当时认为XAML分离不彻底,不好上手。实际上,虽然同为标记语言,但XAML已经比HTML复杂很多了,它里面包含的是,建立控件所需要的高内聚的思想。
(其实当你在做在线应用时,用到控件库的时候,HTML的DIV标签里最多也只是加了一个ID或者加了一个Class属性,而标签内部,如何生成一个控件,全都在所调用的JS代码里。那段JS代码里面会写,里面会生成什么标签,标签的属性是如何定义的,数据是从何而来的。)
WPF中最顶层有一些抽象类和抽象接口,每个抽象类和抽象接口都会有自己的一些抽象的方法,然后也会有自己的属性。每个子类都会继承父类的方法和属性,然后子类再集成一些接口的方法和属性,再自定义一些方法和属性。子类就会比父类有更多的特征。从而演化出了WPF中那么多的类,那么多的控件(控件都是类,但类并非全部是控件,控件是和用户交互的媒介)。
服务器端控件和浏览器端(以及客户端)控件
在准备谈控件级别的结构、行为、表现分类这样的概念前,我们可以先从另一个角度来看看控件分类,这会对我们理解后面的内容有帮助。
早期的ASP.Net开发,Java开发,用的都是服务器端控件。这些控件会被包在一个Form里,当控件想要获取数据,或者激发事件的时候,整个控件都会被提交给服务器,服务器将数据加载给控件后,再把整个控件提交到客户端或者浏览器端。这样的坏处,就是不必要的将标记语言,以及控件逻辑等等都发送到服务器,再发送回来,非常影响效率。但服务器端控件并不是一无是处的,面对着惨烈的互联网军备竞赛——浏览器大战,造成的不兼容性,服务器端控件,能很好的做到跨浏览器支持。服务器端控件包含着对DOM的解析,而不依赖于浏览器对DOM的解析,所以其兼容性很好。
后来大家认识到将控件结构和控件逻辑在服务器和客户端反复传输是极大的浪费,就有了异步传输的概念,在浏览器开发上,就是用HttpGetRequest方法去获取服务器端数据,在浏览器端,通过JS控制控件结构和属性的更改。这也就是大家所熟知的AJAX技术。这些封装了AJAX技术的控件,往往被称作浏览器端控件。
而在很多需要跟服务器进行数据交换的软件中,也意识到同样的问题,客户端应用的软件商,控件也得到了充分的分离,我们姑且也可以把这类控件叫做客户端控件。
控件构成

上面这张图是我简单刻画的一张概念图,上一篇讲的容器和面板,其实只是右上角Structure里的内容。我将控件总共概括为这六方面的内容:内容、结构(元素和布局)、逻辑(功能和方法)、事件(触发器)、属性、样式。
我们可以将一个按钮控件按这个结构解剖开来:
| 内容: | 按钮上的文字或其他内容 |
| 结构: | 整个背景框、感应区域、内容 |
| 逻辑: | 可以点击(Click)、感应鼠标等输入设备(MouseOver、MouseOut、onFocus)、可以释放(MouseRelease) |
| 事件: | 载入(load)、点击、响应事件 |
| 属性: | 宽、高、内容属性、布局属性、输入区进出感应区状态(onMouseOver、onClick、hover) |
| 样式: | 给属性设置值。 |
抽象层次的分类:
如果按上一篇我们提到的结构、表现、行为相分离的概念,那么内容和结构应该对应着之前提到的结构,属性和样式应该对应之前提到的表现,而事件和逻辑应该对应之前的行为。当然,没有对应的那么完美,比如属性和逻辑,又有点像表现和行为的交叉领域;内容有时有关乎于表现。在这种抽象层面的探讨上,有时就很难归类,难说哪种归类最优秀。不同的平台,往往在这种抽象层面上有不同的分类,虽然这些分类大致类似,但总有些问题是很难归纳,模棱两可的,这些问题在不同的平台上会产生不同的归纳。
如果有人告诉你,学啥语言不要紧,学啥软件不要紧,那么他一定是在装逼。因为在不同语言或者不同平台上,它最抽象层次的归纳可能是非常不同的,当你的需求越来越高,越来越具体的时候,有些语言、软件、平台,就会变成瓶颈。
当然,能将这些深层次的问题都看透的人,自然可以很好的理解各种平台下,抽象层次是如何归纳如何实现的,他们可以从抽象层次自己进行修改,来满足自己的需求。当水平达到那个境界的时候,的确可以视语言、软件、平台于无物。
下一篇中,我会具体提到这些抽象分类的思想的来源和依托。讲到设计原初思想的时候,反而没有太多技术上的概念。那里有我信奉的一个真理:世界上最后只有三门学科:哲学、分类学和语言。
抽象就是对复杂的不断分解和提炼:

按钮可能是一种最简单的控件了,所以甚至在用flash做动画时,就可以自定义按钮的感应域啊,自定义鼠标进入、点击、鼠标退出等不同状态下不同的样式。但是想做出一些交互,则还是要在动作面板里写as脚本,写入各种事件。不过只要稍稍想多自定义一些东西,大家都会抛弃flash自带的按钮,而直接针对元素,将元素转化为对象实例,然后给对象添加代码,控制对象的交互行为。(可能设计师接触flash的时候,都是从关键帧动画开始的。但是接触的深了,就会发现,要做交互,就需要很多代码来控制。并且很多效果的变化也不用关键帧动画制作,而是在代码中控制属性的变化。慢慢的,深入下去,可能就会向往学习传说中的flash “一帧流”,哈哈,当然这是题外话了。)
当我们不止是想要做演示,而是要做一个应用程序时,我们遇到的控件就要丰富的多了。然而,即便是再复杂的控件,也是由最简单的控件,不断组合重构而来的。复杂的控件,可能会有很多的层次,其中每一个部分,都可以单独看做一个控件。
比如GridView,特别复杂的会带有过滤(filter)、排序(sort)、即时修改等功能,在结构上,可能带有滚动条,可以移动列宽、行高,每个单元格可以使输入框、按钮、下拉框(ComboBox)、单选框、复选框。甚至还有TreeGridView,可以将内容分层,收缩展开行。
那个时候,虽然控件的逻辑和结构会很复杂,但是不断的通过这六个角度去分析这个控件,还是可以了解一个控件是如何构成的。不过眼下,我们还是简化为四个方面来描述控件。
控件的数据、结构、表现、行为相分离
我特意在结构、行为、表现之前加上了数据。在界面布局上的结构、行为、表现的分离,其主要目的是工作分工上可以更好的独立开来。
对使用者来说,实际上控件方面的分离,主要是要将数据的交换和更新分离出去,Ajax的目的也在于这个。而控件方面的结构、行为、表现上的分离,则是对控件开发者意义重大。
好吧,废话了这么多,我们才刚刚走到控件创新的门口,我有罪。
结构:
| 面板 | 用于放置包含内容的容器,对其进行排列和定位 |
| 容器 | 可以被选定的元素 |
| 装饰器 | 特定类型控件的基本外观组成部件、感应区域 |
| 内容 | 数据或其他子元素 |
一个控件大致包含面板、容器、装饰器和内容四部分。内容除了可以是子元素(即将其他控件放置到该控件内,作为该控件的内容元素),也可以绑定到数据集合。
对于内容控件(包括头内容控件)来说,其结构中,只有内容和装饰器是有意义的。面板和容器,主要针对的是选项控件(包括头选项控件)才有的结构。越是复杂的控件,就包含越多的子元素,子元素往往又包含着各自的面板和容器,而子元素之间往往还有分组和自带的属性。
表现:
| 布局属性 | 空间的大小,放置的位置,对齐方式 |
| 文字属性 | 文字的颜色、大小、字体、对齐等 |
| 状态属性 | 鼠标悬停、鼠标按下,鼠标释放、鼠标离开、选中、没选中、自定义状态 |
| 附加属性 | 依赖项属性、附加属性 |
| 模板 | 内容模板、控件模板、子元素模板、面板模板、容器模板 |
| 编辑模板 | 编辑状态下的控件模板 |
往往每一个元素自身都有前三种属性,而附加属性往往是根据元素所放置的面板或者其他父元素的特征得来的。而模板,则是对现有控件结构的重新定义,包括对控件内容的重新定义,即内容模板;对子元素的重新定义,即子元素模板;控件甚至可以对其面板和容器进行重新定义,那就是面板模板和容器模板了;对控件整体结构的重新定义,即控件模板,控件模板可以同时重定义上述的所有模板。

大部分控件都是只读状态,而有时,我们需要让控件中的部分切换状态,达到就地编辑修改的目的。在以往的方式中,往往是弹出一个包含输入框、选择框的对话框,来重新传递参数,然后更新控件信息。而现在,更聪明的做法是让控件隐藏有一个编辑模板,当用户执行某些操作时,会更改控件的状态属性,控件的编辑模板就显示出来,通常状态下的显示状态就隐藏起来。这个在可编辑的表格中非常常见(Editable GridView)。其实,只要是显示复杂数据的,如果拥有编辑模板,其用户体验就会更好。因为这能保证更好的一致性和更少的跳转。
行为:
| 载入 | 窗口载入、文档载入、控件载入 |
| 切换 | 状态切换 |
| 布局变化 | 展开、收缩、隐藏、拖拽、停靠 |
| 计时 | 延迟响应 |
| 焦点 | 失去焦点(lostfocus)、获得焦点(focuson) |
| 其他输入 | 键盘输入等等 |
行为往往针对的是控件来说的,行为主要是用于触发控件的变化的:数据改变、结构改变、表现改变。我认为可以把行为概括为控件的方法,和用于触发控件调用方法的事件的总和。
这里有个有趣的观点就是,每个属性,往往可以被拆分成两个行为:一个是变成这个属性,一个是失去现有的属性。比如颜色为红,可以拆分为,颜色变成红色,和从红色变成其他颜色(失去红色)。这个在状态属性中特别常见,鼠标悬停,可以看作是,鼠标进入感应区域,鼠标离开感应区域。
在这个认识之下,微软的WPF中,非常提倡用属性来代替事件。我想这可能会是未来的一个趋势,在这个趋势之下,设计师可以方便的通过更改属性来完成自己想要的交互效果,可以和程序员的工作更独立开来。
数据:
| 标量(Scalar) | 一个单独的字符串(string)或数字(numbers),比如"北京"这个单独的词。 |
| 序列(sequence) | 若干个相关的数据按照一定顺序并列在一起,又叫做数组(array)或List(列表),比如"北京,东京"。 |
| 映射(mapping) | 一个名/值对(Name/value),即数据有一个名称,还有一个与之相对应的值,这又称作hash(散列)或dictionary(字典),比如"首都:北京"。 |
这个表格摘抄自阮一峰写的《数据类型和Json格式》,他是引自YAML的。
数据这个东西,说的简单,可能就是很简单的字符串或者数字,包括我们在前面提到的结构中的内容也好,谈到控件结构分离时的内容也好。比如说按钮上的文字,那就是最简单的标量。
但数据也可以是很复杂,拥有结构的数据,那就是一种信息,可以组成这个世界上的任何东西。而将数据组成一定的结构,那就是分类法。虽然上面写到的数据的第三种结构只是简单的映射(mapping)二字。但映射,其实包含了计算机相关领域的一切精髓。包括前文提到的属性,其实就是一组名/值对,一组字典。包括面向对象编程中类的继承,接口的继承,也是映射。包括关系型数据库,也是一种映射。包括未来我们可能提到的MVC、ORM,统统都是映射。(题外话:信息架构,就是一门研究数据关系、数据分类的学科,所以信息架构中的很多观点,都会在计算机领域带有一定的前瞻性。类似的前瞻性的学科,还有数学和范畴论等等。)
AJAX技术,早前主要用XML来传输数据,而现在则主流实用JSON来传输数据。XML更普适,带有跨平台的解析能力。而JSON则更轻量,只是针对JS比较好用。
在不同的平台之下,往往不同的语言会设计不同的类,来包装数据的结构,来与控件进行通信,这就又是一个庞大的话题了。
复杂的控件,之所以需要那么复杂,就是为了用优雅的方式,将复杂的数据结构性的表达出来。所以控件的创新之源,应该来自于数据可视化。
用户体验有两个方面,一个可以从人的方面考虑,改善的是交互方式,改变的是行为和输入;另一个则是从机器的方面考虑,改善的是数据的表达,改变的是信息的结构和输出。
如果能从这两方面入手,去完全重定义概念化的控件,那就是交互设计上最大的革新。AR+Tangible UI+新的数据可视化,就是下一代交互系统的模式。如果还记得MIT那个印度小子在TED中展示的第六感技术(SixSenses),不用怀疑,那一定就是下一代交互系统要走的方向。虽然他只展示了一些雏形,但下一代交互系统已经揭开了它冰山的一角。
最后留个思考题:

这是chrome的下载进度条。google设计这样的进度条包含了哪些思想,是怎么实现的。有兴趣的可以用上面的结构分解法来分解下结构,有几层控件的嵌套。圆形进度条是如何实现的,根据下载文件类型不同,上面的图标是如何转换的。欢迎留言聊聊你的思路,大家可以讨论一下。
结语
第二部分的内容大致就此讲完了。虽然拗口的概念少了很多,但是本文又引入了大量新的概念。如果第一篇文章理解了,那此文应该不难理解。
可能对于没有编程经验的设计师来说,这一章引入了类、接口、继承等等概念会让人产生本能的排斥。但了解这些概念真的是非常必要的,并且,相比较过去面向过程的编程,这些面向对象编程的概念,已经越来越接近于我们真实的世界,变得更好理解了。要知道,最早的面向对象编程思想,正是随着最早的GUI界面一同产生的。
如果读到这里你依然对这方面的内容很有兴趣,或者你觉得很有用,那么后面的内容也许将激发你更多的思考和灵感。如果这一部分的内容,让你觉得云里雾里,那可以推荐你先阅读参考资料中推荐的内容,掌握一些相关的知识,并进行实践,我想这部分的知识还是非常有用的。
那么敬请期待下一站——《深入控件创新[3] – 探究控件设计思想》。下一站,我更想做的是从历史开始思考,尝试着去预测未来。到时可能会有更多新的知识扑面而来,加速学习吧。
参考资料
- Flash的“一帧流”:http://bbs.9ria.com/viewthread.php?tid=18737 By AS3天地会
- 用户体验模式(UX Pattern):<Designing Interfaces>,http://www.designinginterfaces.com/ By Jenifer Tidwell
- YUI库:http://developer.yahoo.com/yui/ By Yahoo!
- jQuery:http://jquery.com/ By jQuery Project
- WPF内容模型:http://msdn.microsoft.com/zh-cn/library/bb613548.aspx By MSDN
- 按类别分类的控件:http://msdn.microsoft.com/zh-cn/library/ms754204.aspx By MSDN
- Dr.WPF解剖控件:http://drwpf.com/blog/itemscontrol-a-to-z/ By Dr.WPF
- AJAX实战:<AJAX in Action>,http://www.manning.com/crane/ By Dave Crane, Eric Pascarello & Darren James
- 面向对象编程:http://www.hudong.com/wiki/面向对象编程 By 互动百科
- MVC:http://heim.ifi.uio.no/~trygver/1996/OOUserInterface/column.pdf By Trygve Reenskaug & Taskon Oslo
- 为以后的章节预热:可以试着去了解以下这些内容,信息架构,分面层级系统,ORM,MVC,关系型数据库,面向切面的编程,面向服务的架构。


















aaaaaaaaaaaaaaaaaa
受不鸟啊~~ 召唤id咨询
呵呵,开放投稿功能啦。欢迎你来给我们增添ID资讯啊