WPF/Silverlight编程:大观

零.起始

由于Leopard项目而学习c#/.NET/silverlight已有2个多月了。我在之前已经有5、6年的时间没有接触过任何 Windows的软件开发平台和技术,对windows编程的认识还停留在大学时候学习的一些VC6/MFC的编程技术。在刚一知道需要再次学习 Windows编程的时候,心里还打鼓呢,因为我自从毕业后主要从事的是在开放软件平台上的应用开发,Windows方面已经很生疏了。But,我对C# 还是感兴趣的,因为它的标准是开放的,而且对C#的发明者Anders Hejlsberg很敬仰,相信他所设计的东西一定不同凡响,在学习了c#之后,事实果真如此。我觉得C#/CLR是迄今为止,最易于使用、最优雅、最全 面的编程语言平台,所开发的软件相比c++和java,结构更灵活、更易于维护、更容易适应用户经常变化的需求。

在学习过程中,我首先通过《Head First C#》和《c# 3.0 specification》学习C#语言本身和理解.NET的整体框架,通过对比C++和Java,以及做一些小的软件,比如Head First C# Labs,掌握C#编程语言,这一步还是比较顺畅的。我的感觉,只要对OO思想有较好的认识和实践,这种纯粹编程语言层面上的学习应该不是难事。随后开始 学习silverlight,这一步主要是通过《pro silverlight 3.0 in c#》和MSDN(中文版的语句很不通顺,感觉就像是机器翻译的)来进行的,随着学习的深入,越来越多的概念和我的已有经验相差越来越远,因为相比 QT,BREW,Android等UI开发框架,silverlight有很多的不同,毕竟很长时间没有跟踪windows的软件开发技术了,都是新东 西,太多的新概念、新的设计方法展现出来,搞得我一时摸不清头绪。后来才发现,原来《pro silverlight 3.0 in c#》中的概念细节其实是在《pro wpf in c# 2008》被阐述的(两本书是一个作者);MSDN上的文档只侧重技术点概念的死板说明,对结构、关联方面的说明较少,不适合初学者。归结来说,是学习的 方式有问题,but,绕了弯路而最终搞明白的,理解就更深刻了,大家都有同感吧。

本文就是在摸清头绪之后写出来的。本文:希望通过展现windows最新的UI框架所带给我们的新技术,说明可以为我们的产品开发带来 的新活力、新思路;侧重的是技术的演化,不是特别细节的技术点;希望能够解释windows最新的UI框架所体现的新的软件设计思路和方法,提高自己的软 件开发设计能力;希望给后学者提供学习方式和步骤的参考。

文中纰漏,敬请不吝赐教,一同讨论。

壹.编程语言平台的演化

WPF/Silverlight以C#和CLR为基础,所以要先说说编程语言平台。

C#相比C++,Java,根本的改进就是扩展了类与对象的概念,将“属性(property)”和“事件(event)”当做编程语言的基本要素,同时依赖CLR环境,实现配套的编程设施。C#的这个改进可以说是软件开发技术发展的必然结果。

软件开发就是把现实世界的问题使用计算机编程语言实现,以便更高效的使用计算机硬件来解决现实问题的过程。编程语言做为工具,能否为开发人员提供更简便、更有效的开放方式,是其不断发展的方向。

从汇编语言的“指令”,到脚本语言的“宏”,到面向函数编程语言的“函数、指针”,再到面向对象编程语言的“类、对象”。编程语言提供 的词汇和概念越来越接近开发人员的自然语言,与此同时编程语言也越来越复杂,从简单的指令直接运行发展到需要一个配合的运行虚环境(比如 JVM,CLR)。这些都是因为现实问题的复杂性在变大,所要求的软件的功能也跟着变大,软件变得越来越复杂,开发和维护的难度在持续增加,做为开发的工 具,编程语言的能力也需要进一步提高。同时硬件能力的不断提高,也给软件的发展提供了物质基础,没有新型cpu的支持,JVM和CLR这样的虚拟执行环境 是不可能被应用的。

编程语言能力的提高,体现在什么方面呢?我的看法,就在于编程语言将现实问题域的概念映射到计算机解决方案域的逻辑概念的能力。这种映射越简便、高效、优雅,就说明这种编程语言具有更强大的能力。

考虑需要用户交互的软件,比如GUI应用程序(包括桌面上的、手持设备上的),整个系统都是由事件(可以分为用户触发的事件、系统触发 的事件)驱动运行的,比如用户点击了键盘或者除摸屏幕;来了一个电话;闹铃到时间了,等等,没有事件发生,系统就在那里待机。“事件”就对应了业务需求中 的“当...,就...”这样的描述。C上处理事件,就是从面向过程的角度,使用一个函数调用另一个函数的方式来实现;C++和Java进一步的通过调用 封装在对象中的方法来表现。如果这个事件具有广播的性质的,比如一个usb设备的插入,既需要在状态栏更新出一个usb设备的图标,又需要在当前窗体上更 新出这个usb设备的详细信息,这种一个事件的发生需要同时有多个处理也是很常见的需求。对于C++/Java来说,只能应用设计模式的思维,实现MVC 模式来实现。而C#通过直接提供的event关键字,由语言平台本身直接支持,这样更简便和优雅。当然,要实现这样的功能,其背后的实现相比 C++/Java更复杂了。

面向对象的基本,就是把问题抽象成一个个的整体,这个整体具有动态行为,同时也有静态属性;可以通过调节它的属性,来获得不同的功能。 比如从椭圆获得一个圆,可以通过调整它的焦点位置,也可以通过设置这个椭圆外接矩形的宽度和高度为相等来获得。在软件开发上,不会单独创建一个椭圆,一个 圆的。属性这个东西在C++/Java里,只是一个逻辑概念,需要使用类中的方法来实现,而且往往就是一对,完成读和写的需要。而不直接使用私有成员变 量,就是在于不能违反OO的数据封装原则。

在C#里,定义类的时候,除了像C++/Java那样具有方法和成员,就是可以直接声明事件和属性。现在,我们可以改变在C++ /Java中的习惯,优先使用属性,而不是私有成员,来表示该类的性质,更重要的,属性可以通过XML文件来使用,这是C++/Java编程环境没有的功 能,而一旦一个类的属性可以被描述化,就可以轻松实现对软件进行二进制层面上的配置,不用重新编译即可获得新的功能。

更多编程语言相关的话题,这里不再详述,因为这个话题本身就很大了。你可以先停在这里,去google相关的资料看看,或者尝试阅读一下c#的编程实例。

休息一下,马上回来...

贰.GUI框架的演化

Sl-sample-effect-button

你认为要怎么实现上图的显示效果和操作效果呢?(操作效果看不出来,就是鼠标在两个按钮上滑动,以及按下的时候,按钮的显示状态会不同。上图显示现在focus在stop按钮上)

先考虑下在BREW 3.x/4.x系统上怎么来做?在Android上又怎么做?或者QT,又或者使用Win32/GDI...

八成你会想,这个需要美工才能做出这么好看的效果。eh,用silverlight,这些都是用XAML来实现,不用写任何c#代码,也不用美工做任何图片,具体怎么做...eh,请看这里:WPF/Silverlight编程:控件定制。这里要介绍下GUI框架的发展,才会更容易的明白为什么WPF/Silverlight可以做得到,而且还比较容易。

我经常在好莱坞大片上看到电影里所使用的GUI人机界面,相当酷,相当炫。每当这时,我就点下pause,琢磨怎么来实现。界面上的基 本元素还是那些,label, button, textbox, listbox,icon...,多的是显示效果:窗体透明了,窗体边框玻璃质花了,边角圆滑了,有各种动态效果,增加触控、拖放的效果,界面元素能动起 来。举个简单的例子,在一个音频播放器窗体上,左右有两个模拟现实功放喇叭前面板的图案,它们会随着音乐的播放有一种实时震动的效果,同时,鼠标滑过控制 按钮一栏,产生出类似mac os中dock panel上的效果?

重点就在于所使用的GUI框架的图像渲染引擎。不过,请注意电脑游戏的界面,呵呵,它们的界面已经有那些效果了,所以...可能你已经可以猜到我会说的东西了:如果把游戏的渲染引擎用到GUI软件上呢?

事实上当然不是直接拿了游戏的图形渲染引擎,而是参照之,使传统的GUI框架的图像渲染引擎有了很大的改进。

WPF/Siverlight就是使用了DirectX,取代了GDI/GDI+,做为新的GUI框架中的图像渲染引擎。当然,考虑到 实际的效能,这里的DirectX并不完整。所以在使用WPF/Silverlight开发GUI程序的时候,可以配置是否要打开硬件加速。因为GDI不 是硬件加速的,换句话说,WPF/Silverlight的图像渲染引擎更多的和GPU结合了。使用Java的图形库也可以做出很酷炫的效果,可是据我所知,实现起来是比较麻烦的。

这样一来,实现酷炫的基础已经具备。

随着硬件水平的不断提高和成本的降低,手持设备具有单独的图形硬件加速芯片将会十分普遍,现在桌面上的图像技术应用到智能手持设备已经成为现实。这一点也可以从WM7的硬件要求看出来,而现在的smart phone还没有普遍装备硬件图形加速芯片。

图形渲染引擎有了性能上的改进后,就是看待GUI界面元素(UI Element)的方式也要进行改进,这方面和WPF XAML的产生有关,参考WPF/Silverlight编程:理解应用程序编程模型中的“XAML的来由和作用、新的开发方式”一节。

GUI框架的另一个演化,在于使用什么形式来组织界面元素。C++本身是不带图形库的,就如C;Java作为一个平台,本身提供了图形 库swing,但是它并没有原生支持使用描述性的方式来组织,要写在代码里;Android上是使用XML来描述的,但是仅限于布局;对界面元素的定制还 是十分的麻烦(要新建类,自己实现重绘回调)。而我们实际需要的不是规规矩矩的button,界面元素的定制事实上已经成了使用这个GUI框架开发的常态 工作。

WPF/Silverlight所提供的机制,远超过Android这类的传统框架所提供的方式,定制界面元素,十分简便。

休息一下,马上回来...

叁.WPF/Silverlight的特点

* 它提供了一种新的XML-Based描述性语言,XAML。不同于Android中使用的XML界面描述语言,XAML和C#代码紧密结合在一起,可以直接在XAML中引用C#中定义的类的属性。因为XAML不仅仅处理界面布局,还可以处理界面元素的数据来源绑定,比如ListBox的内容数据。

* 借鉴Web页的CSS概念,组织UI的Layout。整体是页面式的,类似于Web page,WPF/Silverlight直接管理页面的前进、后退以及历史,可以直接在浏览器中运行。

* 它通过扩展C#/CLR的属性事件,使用“依赖项属性”和“路由事件”更好的为控件定制化服务。前者是为了定制化的控件如何获取数据服务的,后者是为了定制化的控件如何响应用户操作的。

* 属性驱动,事件和方法被看成是围绕属性的操作。属性是声明性的,可以随意进行数据绑定。

* 提供简便的“数据绑定模型”,结合XAML,方便UI上的的数据供给。

* 为控件定义了“内容模型”,这为我们如何看待一个控件,如何分解一个控件建立了新的视角和设计思路。定制化UI控件的关键在于理解这个“内容模型”以及下面的VSM。

* 直接支持动画。开发者只需要在XAML中描述动画的过程,WPF/Silverlight会自动解释它们。实现上,只要使用VisualStateManager(VSM)和Storyboard来描述控件的动态表现,完全不需要写代码。

* 直接支持播放音频和视频文件。连同上一点,都可以归结到是因为WPF/Silverlight使用了DirectX。

* 通过Expression Blend工具,充分允许Designer和Developer并行开发的需求。

* 物理分辨率无关。轻松应付不同尺寸,不同分辨率的的手持设备。

* 开发人员不需要Designer制作具体的图片,然后采用“贴图”的方式;而是需要Designer给出设计要求,比如什么样式,什么颜色,等等。这里不把Designer说成美工,就是为了突出“UI设计”方面。

* 为Web程序和本地应用程序提供了统一的界面,既可以做为Web程序在浏览器中运行,也可以做为普通的应用程序,在本地启动。

肆.下一步

本文重点不是介绍技术细节,更多的关于WPF/Silverlight的控件模型及动画模型的内容,是深入部分。

在学习方式上,Silverlight技术来源于WPF,所以虽然我们是使用Silverlight进行开发,但在学习的过程中,学习 WPF是必要的。根据我的学习实践,当被Silverlight中的一些概念拖住时,应该回头去WPF中去寻找基础概念。在MSDN 上,Silverlight章节中的一些重要概念,就是链接到WPF中的。不过如果是先看WPF,再看Silverlight,可能目的性并不好,而且时 间上往往不允许。更重要的在于开发人员间要多交流和讨论。

在辅助知识上,开发人员需要计算机图形学方面的知识,尤其是一些图形绘制的基本方法,才能更好的进行UI界面的开发,和Designer交流的时候也会更有效率。如基本的颜色系统、画刷概念、调色板、绘画路径,等等。这些都是在需要的时候,进行不断积累的。

WPF/Silverlight借鉴了Web程序的组织特点,所以还需要开发人员对Web开发有一些基础知识,比如Web页的结构,CSS,Page element,等等。这些都是很基础的内容,只需要按需学习即可。

总结一下:WPF/Silverlight提供了一种新的应用程序开发方式和相关的技术,使用它,在开发流程上,可以最大化的将UI设 计人员和开发人员的工作并行化;对于UI设计人员来说,可以更多的参与到项目的开发中,而不是简单的美工工作;对于开发人员来说,可以十分方便的定制UI 界面,这种改进相对于传统的如Java Swing,Android的那种实现EventListener+重绘的方式,是全新的设计思路,加速了开发周期。具体的内容,参考WPF/Silverlight编程:理解应用程序编程模型

posted @ 2013-01-04 14:22 Leo L.Cao 阅读(...) 评论(...) 编辑 收藏