汹涌澎湃汹涌澎湃汹涌澎湃汹涌澎湃
Windows演示基础(Windows Presentation Foundation,WPF)是一个用于Windows平台的全新的图形显示系统。WPF是针对.NET而设计的,它受现代显示技术(如HTML和Flash)以及硬件加速技术的影响。WPF也是Windows 95以来对Windows用户界面影响最深刻的技术。
本章将首先介绍WPF的体系结构;将讨论WPF如何处理可变屏幕分辨率,并将概述WPF的核心程序集和类。还将介绍WPF 4提供的新特性,首先会介绍WPF的工作原理,以及它如何为开发下一代Windows应用程序提供支持。
新增功能:
如果以前使用过WPF,您可能希望直接跳到本章后面的“WPF 4”一节,该节总结了最新WPF版本中的变化。
1.1 Windows图形演化理解Windows图形
超过15年以来,Windows开发人员一直在使用本质上相同的显示技术,如果您不了解这一实际情况,就很难体会到WPF的变化有多大。标准Windows应用程序依靠Windows操作系统的如下两个由来已久的个部分来创建用户界面:
● User32 该部分为许多元素(如窗口、按钮和文本框等)提供了熟悉类似的Windows外观。
● GDI/GDI+ 该部分为渲染简单形状、文本以及图像提供了绘图支持,但增加了复杂程度(而且通常性能较差)。
在过去几年中,这两种技术已经得到改进,而且开发人员使用的与其交互的API也已经发生了很大变化。但在构建应用程序时,不管使用.NET和Windows窗体,还是使用过去的Visual Basic 6或基于MFC的C++代码,在底层都是使用Windows操作系统的相同部分来工作的。较新的框架工具只是为与User32和GDI/GDI+进行交互提供了更好的包装器而已为使用User32和GDI/GDI+进行交互提供了更好的封装。这些框架工具能够提高了效率,降低了复杂性,并且提供了更多的预置特性,使从而开发人员不必再自己编写底层代码,但这些框架工具不可能避免在十多年前设计的系统组件在设计上的基本限制,这些限制已经存在了十多年。
注意:
在超过15年前,在Windows 3.0中建立了User32和GDI/GDI+的基本分工版本。当然,User32在那时简化了用户操作,因为那时软件尚未进入32位的世界。
1.1.1 DirectX:新的图形引擎
Microsoft针对User32和GDI/GDI+库的限制,提供了一个解决方案:DirectX。DirectX起初是一个容易出错的组合性工具包,用于在Windows平台上开发游戏。DirectX在设计上重点关注的是速度,为此,Microsoft和显卡供应商紧密合作,以便为DirectX提供复杂的纹理映射、特殊效果(如半透明)以及三维图形所需要的硬件加速功能。
在DirectX第一次发布DirectX(在Windows 95发布之后不久发布)后历经数年的发展的,DirectX变得很成熟了。现在DirectX已经成为Windows的基本组成部分,支持所有现代的显卡。然而,DirectX编程API,正如其设计初衷,仍然主要是作为游戏开发人员的工具包。因为它本来就很复杂,所以DirectX几乎不用于开发传统类型的Windows应用程序(如商业软件)。
WPF一举扭转了这种局面。在WPF中,底层的图形技术不再是GDI/GDI+,而是DirectX。需要强调的是,不管创建哪种用户界面,WPF应用程序在底层都是使用DirectX。这意味着不管是设计复杂的三维图形(这是DirectX的特长),还是仅仅绘制几个按钮以及纯文本,所有的绘图工作都是通过DirectX管线来完成的。因此,即使是再普通不过的商业应用程序也能使用丰富的效果,如半透明和反锯齿。在硬件加速方面也带来了好处,DirectX在渲染图形时会将尽可能多的工作交给图形处理单元GPU(GPU图形处理单元)进行处理,GPU是显卡专用的处理器。
注意:
因为DirectX能够理解高层的元素,例如纹理和渐变,这些元要素可以由显卡直接渲染,所以DirectX效率更高。而GDI/GDI+不理解这些高层元素,所以需要将它们转换成逐像素指令,而通过用现代显卡渲染这些指令是非常更慢的。
User32在一定程度上仍然被保留了下来。因为对于特定服务,WPF仍依赖于User32,例如,处理和路由输入信息以及区分哪个应用程序实际拥有屏幕的哪一部分。但是,所有的绘图操作都是由DirectX完成的。
注意:
对于GDI/GDI+,WPF不再是一个GDI/GDI+的封装器,而是GDI/GDI+的替代技术,是一个通过DirectX进行工作的独立层次,这是在WPF中最显著的变化。
1.1.2 硬件加速与WPF
您可能知道显卡在支持特定渲染特性和优化方面的区别。幸运的是,这不是问题,因为WPF使用软件计算(而不是依赖于显卡提供的内置支持)来执行任何渲染操作。
当使用DirectX进行编程时,这可能是最令人头痛的问题。而使用WPF则可以不必关心显卡的问题,因为通过使用软件计算而不依赖显卡提供的内在支持,WPF可以执行任何渲染操作。
注意:
对于WPF软件支持有一个例外。因为驱动程序的支持不够好,只有在Windows Vista或Windows 7(并在本地为显卡安装了本地WDDM有Windows Vista显卡驱动程序)上运行应用程序时,WPF才会为三维绘图操作提供反锯齿处理。这意味着也就是说,如果在使用安装Windows XP的计算机上绘制三维图形,最终的图形边缘会出现轻微的锯齿而不是平滑的线条。然而,对于二维绘图,WPF仍然提供反锯齿处理,而不管使用的是哪种操作系统,也不管驱动程序是否支持。
具有一块功能强大的显卡并不能绝对保证在WPF中一定能获得硬件加速功能。软件仍具有非常重要的作用。例如,如果显卡使用过期的驱动程序,WPF就不能为显卡提供硬件加速功能(如果使用旧式显卡,在零售发布包中可能只能提供这些过期的显卡驱动程序很有可能是在零售发布包中提供的)。在Windows Vista和Windows 7操作系统中,WPF可以提供更好的性能,因为WPF可以充分利用Windows Vista显示驱动模型(Windows Vista Display Driver Model,WDDM)。相对于Windows XP 的显示驱动模型(Windows XP Display Driver Model,XPDM),WDDM提供了几处非常重要的改进。其中最重要的改进是,WDDM允许同时调度多个GPU操作,并且当所需的显存量超出所能得到的显存量时,允许显存内容整页面地转到常规系统内存中。
作为一条经验法则,WPF为2004年11月之后创建的所有WDDM(Windows Vista)驱动程序和2004年11月之后创建的XPDM(Windows XP)驱动程序提供了几类硬件加速功能,2004年112月,Microsoft发布了新的驱动程序开发指导原则。当然,支持的程度是有所不同的。当WPF基础架构第一次启动时,它会对显卡进行评估,并为显卡指定一个等级(从0级到2级),如下面的补充说明“WPF渲染级别”所述。
第一次出现的时候,通过在显卡旁边印上“WPF Tiers”来评价显卡的性能,并对显卡从0级到2级进行分级。
作为WPF承诺的一部分,不必担心特定硬件的细节和特点。WPF足够非常智能,它会尽可能利用硬件优化功能,并且为任何操作都提供了软件处理底线。所以如果在一台使用老显卡的计算机上运行WPF应用程序,仍然会以您所期望的方式显示用户界面。当然,使用软件处理的替代方法,速度会非常缓慢,所以您会发现在使用老显卡的计算机上不能很好地运行很好地运行富WPF应用程序,特别是那些包含复杂动画或其他强大图形效果的WPF应用程序。实际上,可以根据客户端的硬件加速支持级别(由RenderCapability.Tier属性指示),来减少用户界面中复杂的特殊效果。
注意:
WPF的目标是将尽可能多的工作交给显卡进行处理,所以复杂图形绘制通常属于渲染范围(即受GPU的限制)而不属于处理器范围(受计算机CPU的限制)。通过这种方式也就是说,可以让CPU空闲下来去完成其他工作,充分利用显卡的功能,并且还可以充分利用未来新显卡所具备的不断提升的性能优势。
WPF渲染级别
显卡的功能相差很大的区别是非常重要的。当WPF评估显卡时,它会考虑许多因素,包括显卡上RAM的数量、对像素着色器(pixel shader)的支持(显卡提供的计算每个像素效果的内置程序,如透明效果),以及对顶点着色器(vertex shader)的支持(显卡提供的计算每个三角形顶点数值的内置程序,如3D对象的着色)。根据这些细节,WPF会指定一个渲染级别值。
WPF能够识别提供了三个渲染级别,如下所示:
● Rendering Tier 0:显卡将不提供任何硬件加速功能。该级别和7.0或更低版本的
DirectX相对应。
● Rendering Tier1:显卡可以提供部分硬件加速功能。该级别和7.0以上9.0以下版本的
DirectX相对应。
● Rendering Tier2:所有的特性都将由硬件加速。该级别和DirectX 9.0及以上版本相对应。
某些情况下,可能想希望通过程序来检查当前显卡的渲染级别,从而可以酌情为功能较差的显卡禁用一些图形特性。为此,需要使用System.Windows.Media.RenderCapability类的Tier静态属性。但是还需要一个技巧。为从通过Tier属性中提取检查显卡的WPF渲染级别值,需要将它移动16位,如下所示:
int renderingTier = (RenderCapability.Tier>>16);
if(renderingTier == 0)
{ … }
else if(renderingTier == 1)
{ … }
这种设计允许在以后可以进行扩展。在WPF的未来后续版本中,可使用Tier属性的其他位来保存对其他特性支持情况的信息,从而创建子渲染级别。
有关tier1和tier2为哪些WPF特性提供了硬件加速的更多WPF特性详情,以及常见的tier1和tier2显卡示列表,请访问(VS.100).aspx。
1.2 WPF:高级API
如果WPF仅通过DirectX提供硬件加速功能,那么它只能算是一项重要的改进,而不是一个革命性的变化。实际上,WPF包含了一整套面向编程人员的高级服务。
下面是WPF引入到Windows编程领域中的一些最重要变化:
● 类似Web的布局模型。与通过特定具体的坐标将控件固定在具体的位置不同,WPF加强了灵活的流式布局,强调根据控件的其内容灵活地排列排列控件的流式布局。从而使用户界面能够适应变化很大的内容,以及不同的语言根据显示的内容和不同的语言灵活地进行调整。
● 丰富的绘图模型。与逐个像素进行绘制不同,在WPF中可以直接处理图元—— 基本形状、文本块以及其他图形元素。也可以使用其他新特性,例如,真正的透明控件,放置多层并且具有不同透明度内容层次的功能,以及本地3D支持功能。
注意:
WPF对3D图形的支持还不如Direct3D和OpenGL那样成熟。如果计划设计高性能的三维绘图程序(如实时游戏),WPF可能还不能提供所需要的特性和性能。
● 丰富的文本模型。多年来对文本的处理一直不规范,一直都是在使用功能较弱的控件来处理文本,如经典的Label控件,这种处理文本的方式还不够好。现在WPF最终为Windows应用程序提供了在用户界面的任何位置显示丰富的样式化文本的功能。甚至可将文本和列表、浮动的图形以及其他用户界面元素结合起来。并且如果需要显示大量文本,还可以使用高级的文档显示特性,例如换行、分列和对齐,以提高可读性。
● 作为首要编程概念的动画。在WPF中,不再需要使用虽然可以使用计时器来强制窗体重绘绘自身以得到动画效果。反而,但是在WPF中,动画称为WPF框架的固有功能部分。在WPF中可以使用声明式标记定义动画,并且WPF会自动让它们动起来。
● 支持音频和视频媒体。以前的用户界面开发工具包(例如Windows窗体)对处理多媒体的处理有很大的限制。但是WPF支持播放任何Windows媒体播放器所支持的音频和视频文件,并且允许同时播放多个媒体文件。更引人注目的是,提供了WPF提供了允许在用户界面的其他部分集成视频内容的工具,以及允许添加特殊效果的技巧,例如,在一个旋转的3D立方体上放置视频窗口。
● 样式和模板。通过样式可以实现允许显示格式的标准化,并且可以在各个整个应用程序之中间重复使用。通过模板可以允许改变元素的渲染方式方法,甚至改变核心控件(如按钮)的渲染方法式。在创建现代的具有皮肤的用户界面方面,从来没有像现在这样方便。
● 命令。大多数用户已经认识到,通过菜单或工具栏触发Open命令都并没有什么区别,最终结果是相同的。现在通过代码抽象,可在特定的位置定义应用程序命令并将它链接到多个控件上。
● 声明式用户界面。尽管可以通过编写代码创建WPF窗口,但Visual Studio提供了另一种方式。它将各个窗口的内容串行化到一个XAML文档中的一套XML标签中。其优点是用户界面和代码完全分离,并且图形设计人员可以使用专业工具编辑XAML文件,并最终改进应用程序的前端界面。XAML是Extensible Application Markup Language(扩展应用程序标记语言)的缩写,第2章将详细介绍XAML的相关内容。
● 基于页面的应用程序。使用WPF可以创建类似浏览器的应用程序,这类应用程序可以通过“前进”和“后退”导航按钮在一组页面中移动。由WPF来处理那些复杂的细节,如页面历史。甚至可以将项目部署为运行于IE中的基于浏览器的应用程序。
1.2.1 Windows窗体将继续保留
WPF是一个用于未来Windows用户界面开发的平台。但是,它不可能一夜之间一下子完全取代Windows窗体。在许多方面,Windows窗体是上一代显示技术的至高点,它构建于GDI/GDI+以及User32之上。
那么当着手设计一个新的Windows应用程序时,应当选择哪个平台呢?如果是从头开始,那么WPF是理想的选择,它将为未来增强提供最好的前景,并将在很长一段时间内繁荣发展。同样,如果您需要WPF提供的(而Windows窗体没有提供的)特性,例如3D绘图或基于页面的应用程序—— 那么选择使用WPF也是合乎情理的。但如果已经投入相当庞大的资金开发了基于Windows窗体的商业应用程序,那么就不必针对WPF对应用程序进行重新编码。在未来数年内仍将继续支持Windows窗体平台。
关于这个问题可能最好的一部分是,Microsoft已经付出大量努力来构建WPF和Windows窗体之间的互操作层(这一互操作层与允许.NET应用程序继续使用原来的COM组件的互操作层的作用类似)。在第30章将学习如何使用这个互操作层在WPF应用程序中驻留宿主Windows窗体控件,以及如何在Windows窗体应用程序中使用WPF控件。WPF为和老式的Win32风格的应用程序进行集成,也提供了类似的可靠支持。
1.2.2 DirectX也将继续保留
有一个应用领域中WPF能很好地胜任工作:创建要求较高的实时图形应用程序,例如,基于复杂物理过程的模拟器或要求苛刻的动作游戏。如果希望使这类应用程序最大限度地利用显卡的性能,就需要使用原始的DirectX开发接口在更低层次上编写代码。可从. com/directx网站上为DirectX编程下载托管的.NET库。
注意:
随着WPF 3.5 SP1的发布,Microsoft开始打破DirectX和WPF之间的一些界限。现在已经能够使用DirectX内容并将其放置到WPF应用程序中。实际上,甚至可将DirectX内容用于画刷,并使用画刷绘制WPF控件,或将DirectX内容构建进一幅纹理并将其映射到一个WPF 3D表面上。尽管WPF和DirectX之间的集成知识超出了本书的范围,但是可以通过MSDN文档学习更多内容,可以从开始。
1.2.3 Silverlight
与.NET Framework一样,WPF也是一种以Windows为中心的技术。这意味着WPF应用程序只能用于运行Windows操作系统的计算机上。基于浏览器的WPF应用程序也受到同样的限制—— 它们也只能运行在Windows计算机上,尽管它们支持Internet Explore和Firefox两种浏览器。
这些限制是不能改变的—— 毕竟,Microsoft推出WPF的目标是为了利用Windows计算机的丰富功能以及在各种技术(如DirectX)上的投资。然而,Silverlight使用WPF平台的一个子集,通过一个插件可以把它驻留宿主于任何现代浏览器中(包括Firefox、Google chrome以及Safari),并且对其他操作系统(如Linux和Mac OS)也是开放的。这是一个宏大的项目,吸引了相当多的开发人员参与进来。
在许多方面,Silverlight是基于WPF的,并且它包含了许多WPF的约定(例如将在下一章学习的XAML标记)。但是,Silverlight没有包含WPF的所有特性,例如真正的三维绘图以及富文档显示。在将来发布的Silverlight版本中可能会包含一些新特性,但是更复杂的特性可能永远不会纳入。
Silverlight的终极目标是提供一个强大的面向开发人员的Adobe Flash的竞争者。但Flash有一个重要的优点——它已经被用于整个Web领域,并且Flash插件已经被安装到任何地方。为了诱使开发人员转到使用一种新的、尚不成熟的技术上,Microsoft还需要确保Silverlight具有新一代特性、可靠的兼容性以及独一无二的设计支持。
注意:
Siliverliht有两类潜在用户:准备创建具有更好交互功能应用程序的Web开发人员,和准备扩展应用程序的Windows开发人员。要学习Silverlight的更多内容,可以参考专门的书籍,如Pro Silverlight 3 in C#,或者访问。
1.32.1 分辨率无关性
传统的Windows应用程序会受到特定的假定屏幕分辨别率的限制。在设计窗口时,开发人员通常假定一个标准的显示器分辨率(如1024像素×768像素),在设计窗口时需要考虑这个假定的屏幕分辨率,并且针对更小或更大的分辨率要尽量保证窗口能够合理地改变尺寸。
问题是传统Windows应用程序的用户界面是不可伸缩的。所以,如果使用更高的显示器分辨率,会将像素会排列得更紧密,应用程序窗口将变得更小并且更加难以阅读。特别是对于使用像素排列更加紧密的新式显示器,当以较高相应的高的分辨率运行时,问题更趋严重。例如,通常可以发现用户使用的有些显示器(特别是便携式电脑的显示器)的像素排列密度是120dpi或144dpi(dot per inch,每英寸像素点数),超过更为普遍的96dpi。当在这些显示器使用它们默认的分辨率时显示器上,像素会以更紧密的方式显示,从而使控件和文本变得更小。
理想情况下,应用程序应当使用更高的像素密度显示更多细节。例如,一个高分辨率的显示器可以显示相同大小的工具栏图标,但使用更多像素可以显示更清晰的图形。从而可以保持相同的基本布局但是增加了清晰度和细节。出于多种原因,这种解决方法在过去是不可能实现的。尽管可以改变使用GDI/GDI+绘制的图形内容的大小,但是User32(负责为显示通用控件生成可视化外观)不支持真正的缩放。
在WPF中,这个问题不复存在就,因为WPF能够自己渲染所有的用户界面元素,从简单的形状到通用控件(如按钮)。所以,如果在计算机显示器上创建一个1英寸宽的按钮,在更高分辨率的显示器上它将仍然能够保持1英寸的宽度—— WPF只是使用更多的像素更详细地渲染这个按钮罢了。
注意:
当打印窗口中的内容时,分辨率无关性还可以提供更多的优点,这些优点将在第20章中介绍。
这只是一个宏伟的蓝图是基本情况,但是通过几个细节进行了解释还没有涉及细节。最重要的是需要认识到WPF根据分辨率来缩放系统DPI设置进行缩放,而不是根据缩放物理显示设备的DPI进行缩放。,这是需要明确的更重要的内容。说到底这样感觉更好——毕竟,如果在一个100英寸的投影仪上显示应用程序,您可能会站在离投影仪后面几步更远的地方,并希望看到特大版本的窗口。,而不希望WPF骤然间将应用程序缩小到“正常”尺寸。同样,如果使用具有更高分辨率显示器的便携式计算机,您可能希望具有看到稍小的窗口—— 这是在更小屏幕上显示信息所必须付出的代价。更进一步来讲,不同用户有不同的选择。有些用户可能希望显示更丰富的细节,而另外一些用户可能希望显示更多的内容。
那么WPF如何确定应用程序窗口的大小呢?简单地来讲,就是当WPF计算窗口尺寸时使用系统DPI设置。但是如果要理解底层的工作原理,进一步探讨WPF度量系统是很有帮助的。
1.3.11 . WPF单位
WPF窗口以及其中的所有元素都使用设备无关单位(device-independent unit)进行度量(device-independent unit)。一个设备无关单位被定义为1/96英寸。为了理解它的实际含义,下面分析一个例子。
设想使用在WPF中创建一个尺寸为96×96单位的小按钮。如果使用标准的Windows DPI设置(96dpi),每个设备无关单位实际上对应一个物理像素。因为对于这种情况,WPF使用以下公式进行计算:
[物理单位尺寸] = [设备无关单位尺寸]×[系统DPI]
= 1/96英寸×96dpi
= 1像素
本质上,WPF假定使用96个像素构成1英寸,因为这是Windows操作系统通过系统DPI设置告诉WPF的。但是,实际上依赖于显示设备。
例如,考虑一个20英寸的最大分辨率为1600像素×1200像素的19英寸LCD显示器。使用勾股定理,可以计算出这个显示器的像素密度,如下所示:
[pic]
在这种情况下,像素密度达到100dpi,比Windows假定的数值稍高。因此在这个显示器上,一个96像素×96像素的按钮将稍小于1英寸。
另一方面,考虑分辨率为1024像素×768像素的15英寸LDC显示器。对于这种情况,像素密度降低到大约85dpi,因此96像素×96像素的按钮看起来比1英寸稍大。
在这两种情况下,如果减小屏幕尺寸(比如说,将分辨率切换到800像素×600像素),那么按钮(以及屏幕上的其他内容)将相应放大。这是因为系统DPI仍然使用96dpi。换句话说,Windows继续假定96像素代表1英寸,尽管在更低的分辨率下像素更少。
提示:
正如您所了解的您可能会感到迷惑,LCD显示器被设计成在特定分辨率下的效果最好成具有单一分辨率,该分辨率称为自然分辨率(native resolution)。如果降低分辨率,LCD显示器必须使用插值填充额外的像素(这又必然会导致模糊)。为了获得最佳显示效果,最好始终LCD显示器最好使用自然分辨率。如果希望更大的窗口、按钮和文本,应考虑修改系统DPI设置(如下所述)。
2.1.3.2 系统DPI
到目前为止,WPF按钮示例和其他类型Windows应用程序中的任何其他用户界面元素完全一样。如果改变系统DPI设置,结果就不同了。在上一代Windows中,这个特性有时称作大字体。因为那时系统DPI会影响系统字体的大小,但其他细节通常不变。
注意:
许多Windows应用程序不完全支持更高的DPI设置。在最坏的情形下,增加系统DPI可能会使窗口中的有些内容被缩放放大,但是其他内容没有被缩放放大,这可能导致有些内容被隐藏,甚至窗口不能使用。
这正是WPF的不同之处。WPF本身就支持系统DPI设置。例如,如果将系统DPI设置改为120dpi(高分辨率显示器的用户通常选择这么做),WPF假定它需要120个像素来填满1英寸的空间。WPF使用以下公式计算如何将逻辑单位变换为物理设备像素:
[物理单位尺寸] = [设备无关单位尺寸]×[系统DPI]
= 1/96英寸×120dpi
= 1.25像素
换句话说,将系统DPI设置为120dpi时,WPF渲染引擎假定一个设备无关单位等于1.25个像素。如果显示一个96×96大小的按钮,物理尺寸将实际为120像素×120像素(因为96×1.25=120)。这正是所期望的结果—— 一个在标准显示器上大小为1英寸的按钮,在像素密度更高的显示器上仍然保持1英寸的大小。
这种自动缩放如果只用于按钮的意义并不大。但是WPF对它所显示的任何内容都使用设备无关单位,包括形状、控件、文本以及任何其他放置在窗口中的内容。所以,可将系统DPI改变为任何所希望的数值,WPF将无缝相应地调整应用程序的尺寸。
注意:
根据系统DPI计算出的像素尺寸可能是一个小数。可以假定WPF简单地将度量尺寸舍入为最接近的像素。然而,(实际上,WPF支持像素衔接(pixel-snapping)特性,从而可以正确地处理小数像素,在第13章中将学习如何为特定的部分内容启用这一特性)。但是在默认情况下,WPF的处理方式与此不同。如果一个元素的一条边落在两个像素之间,WPF将使用反锯齿特性把这条边混合到相邻的像素。这看起来可能是多余的选择,但是确实可以改进视觉效果。如果为了给控件增加皮肤效果而使用自定义绘制图形,那么就不一定会整齐地、清晰地定义边缘,从而而是需要进行一定程度的反锯齿处理。
调整系统DPI的步骤取决于根据操作系统。后续部分解释了如何根据使用的操作系统调整系统DPI。的不同而不同。对于
(1) Windows XP,具体步骤如下:
a. 右击桌面并从上下文菜单中选择Display菜单项。
b. 选择Settings选项卡并单击Advanced按钮。
c. 在General选项卡上,选择Normal Size(96dpi)或Large Size(120dpi)。这是针对Windows XP的两个推荐的选项,因为老的应用程序很可能不支持自定义的DPI设置。如果要测试自定义的DPI,选择Custom Setting选项。然后指定一个特定的百分比值(例如,175%,将标准的96dpi放大到168dpi)。
(2) 在Windows Vista中改变系统DPI的步骤如下:
a. 右击桌面并从上下文菜单中选择Personalize菜单项。
b. 在左边的链接列表中,选择Adjust Font Size(DPI)。
c. 选择96或120dpi。或单击Custom DPI按钮,从而使用一个自定义的DPI设置。还可以指定一个百分比数值,如图1-1所示(例如,如175%,将标准的96dpi放大为168dpi)。此外,当使用一个自定义DPI设置时,还可以使用一个Use Windows XP Style DPI Scaling选项,后面的“Windows Vista和Windows 7 DPI缩放”补充说明会对这个选项进行说明。
[pic]
图1-1 改变系统DPI
(3) Windows 7
a. 右击桌面并从上下文菜单中选择Personalize菜单项。
b. 在窗口左下角的链接列表中,选择Dispaly。
c. 在Smaller(默认选项)、Medium以及Larger选项之间进行选择。尽管这些选项使用缩放百分比(100%、125%以及150%)进行描述,它们实际上与DPI值96、120和144相对应。您可能会注意到前两个选项与Windows Vista和Windows XP中的标准设置是相同的,而第三个选项更大一些。此外,为了使用一个自定义的DPI百分比,可以单击Set Custom Text Size,如图1-1所示(例如,175%将标准的96dpi放大为168dpi)。当使用自定义DPI设置时,还可以使用Use Windows XP Style DPI Scaling选项,下面的“Windows Vista和Windows 7 DPI缩放”补充说明描述了这个选项。
Windows Vista和Windows 7 DPI缩放
因为旧式的应用程序不支持较高的DPI设置,所以Windows Vista引入了一种称为使用了一种新技术:位图缩放的新技术。Windows 7也支持这一特性。
通过缩放位图,当如果运行一个不支持高DPI设置的应用程序时,Windows Vista会将Windows会改变其尺寸内容的尺寸改变为所期望的DPI,就像它是一幅图像那样。这种方法的样做的优点是应用程序仍然认为它运行在标准的96dpi设置下。Windows无缝相应地变换输入(如鼠标单击),并将输入传递到应用程序的“真正”坐标系统下的正确位置。
WindowsWindows Vista使用的是一种个非常好的缩放算法—— 该算法会考虑像素边界以避免模糊边缘,并使用显卡硬件尽可能地提高速度—— 但是该方法不可避免地会导致一定的显示模糊。它也存在严重的局限性,因为Windows不能识别其实支持较高DPI设置的老应用程序。Windows不能识别那些不支持高DPI设置的老应用程序。这是因为应用程序需要包含一个清单(manifest)或者调用SetProcessDPIAware(在User32中)来公布它们对高DPI设置的支持。尽管WPF应用程序正确地处理了这一步骤,但是在Windows Vista以前创建的应用程序没有使用任何方法,从而即使它们支持更高的DPI设置,也不能使用位图缩放。从而只能使用相对比较理想的位图缩放方法。
有两个可能的解决方案。如果有少数几个特定的应用程序支持高DPI设置,但是并不明确,则可以手动进行详细的配置。为此,在Start菜单中右击启动应用程序的快捷方式,从上下文菜单中选择Properties菜单项。在Compatibility选项卡中,选择Disable Display Scaling on High DPI Settings选项。如果有许多应用程序需要配置,那么很快就会感到厌烦。
另一个可能的解决方法是全部禁用位图缩放。为此,在图1-1中所显示的Custom DPI Setting对话框中,选中Use Windows XP style DPI scaling选项。该方法的唯一限制是在高DPI设置下,可能有些应用程序不能正确地显示(并且可能不能使用)。默认情况下,当DPI设置为120dpi时,选中Use Windows XP style DPI scaling使用Windows XP样式DPI缩放;当DPI设置小于120时,不选择Use Windows XP style DPI scaling不使用Windows XP样式DPI缩放更好一些。
1.3.3 3. 位图和矢量图形
当使用普通的控件时,自然可以利用WPF的分辨率无关性。WPF会小心地确保任何显示内容都能够自动地具有正确的尺寸。但是,如果准备在应用程序中包含图像,偶尔可能出现问题。例如,在传统的Windows应用程序中,开发人员为工具栏命令按钮使用非常小的位图,但是在WPF应用程序中该方法并不理想,因为当根据系统DPI进行放大或缩小时,位图可能出现伪影(变得模糊)。反而,当设计WPF用户界面时,即使是最小的图标,也通常使用矢量图形来实现。矢量图形被定义为一系列的形状,并且它们能够很容易地被缩放为任何尺寸。
注意:
当然,相对于绘制一幅基本的位图,绘制矢量图形需要耗费更长时间,但是WPF包含可减少开销的优化措施,以确保性能处于合理范围之内。
一般不会过高估计分辨率无关性的重要性。因为乍一看,对于这个由来已久的问题(该问题确实如此),它看起来好像是一个简单的、优美的解决方法。但是,为了设计完全可缩放的用户界面,开发人员需要接受一种新的思想。
1.4 WPF体系结构
WPF使用一个多层的体系结构。在顶层,应用程序和一个完全由托管的C#代码编写的一组高层服务进行交互。至于将.NET对象转换为Direct3D纹理和三角形的实际工作,是在后台由一个名为milcore.dll的低级的非托管组件完成的。milcore.dll是使用非托管代码实现的,因为它需要和Direct3D紧密集成,并且它对性能非常敏感。
图1-2显示了WPF应用程序中各层的工作情况。
[pic]
图1-2 WPF体系结构
以下下面是在图1-2中包含的一些重要组件:
● PresentationFramework.dll包含了WPF顶层的类型,包括那些表示窗口、面板以及其他类型控件的类型。它还实现了高层编程抽象,如样式。开发人员直接使用的大部分类都来自这个程序集。
● PresentationCore.dll包含了基础类型,如UIElement类和Visual类,所有的形状类和控件类都继承自这两个类。如果不需要窗口和控件抽象层的全部特征,可以使用这一层,并且仍能利用WPF的渲染引擎。
● WindowsBase.dll包含了更多基本要素,这些要素具有在WPF之外重用的潜能,如DispatcherObject类和DependencyObject类,这两个类引入了依赖项属性(详见第4章)。
● milcore.dll是WPF渲染系统的核心,也是媒体集成层(Media Integration Layer,MIL)的基础。其合成引擎将可视化元素转换为Direct3D所期望的三角形和纹理。尽管把milcore.dll看作是WPF的一部分,但它也是Windows Vista和Windows 7的一个核心系统组件。实际上,桌面窗口管理器(Desktop Window Manager,DWM)使用milcore.dll渲染桌面。
● WindowsCodecs.dll是一套提供图像支持的低级API(例如,处理、显示以及缩放位图与JPEG图像)。
● Direct3D是一套低级API,WPF应用程序中的所有图形都由它进行渲染。
● User32用于决定哪些程序实际占有桌面的哪一部分。所以它仍然被包含进WPF中,但不再负责渲染通用控件。
注意:
milcore.dll有时称为“托管图形”引擎。与公共语言运行库(CLR)管理.NET应用程序的生命期非常类似,milcore.dll管理显示状态。而且正如CLR使开发人员不用再为释放对象和申请内存而烦恼一样,milcore.dll让开发人员不用再考虑使窗口无效和重新绘制窗口。只需使用希望显示的内容创建对象即可,当拖动窗口、窗口被覆盖与不被覆盖、最小化窗口和还原窗口时,由milcore.dll负责绘制窗口的恰当部分。
需要明确的最重要的事实是,在WPF中所有绘图内容都是由Direct3D渲染的。不管是使用普通的显卡还是使用功能更强大的显卡,不管是使用基本控件还是绘制更复杂的内容,也不管是在Windows XP、Windows Vista还是在Windows 7上运行应用程序。甚至二维图形和普通文本也被转换为三角形并被传送到Direct3D管线,而不是使用GDI+或User32渲染图形。
类层次结构
本书将用大量篇幅研究WPF的名称空间和类。但在开始前,首先分析一下构成WPF基本控件集合的类的层次结构是很有帮助的。
图1-3简要显示了类层次结构中的几个重要分支。本书将深入分析这些类(以及它们之间的关系)的细节。
[pic]
图1-3 WPF的主要类
下面将简要介绍图1-3中的核心类。这些类中的许多类构成了完整的元素分支(如形状、面板以及控件)。
注意:
WPF核心名称空间以System.Windows开头(如System.Windows、System.Windows. Controls以及System.Windows.Media)。唯一例外是由System.Windows.Forms开头的名称空间,它是Windows窗体工具包的一部分。
1. System.Threading.DispatcherObject类
WPF应用程序使用熟悉的单线程亲和(single-thread affinity,STA)模型,这意味着整个用户界面由一个单独的线程拥有。从另一个线程与用户界面元素进行交互是不安全的。为了更方便地使用此模型,每个WPF应用程序由一个协调消息(从键盘输入、鼠标移动到框架处理,如布局)的调度程序管理。通过继承自DispatcherObject类,用户界面中的每个元素都可以检查代码是否在正确的线程上运行,并且可以访问调度程序为用户界面线程封送代码。在第31章中将介绍有关WPF线程模型的更多内容。
2. System.Windows.DependencyObject类
在WPF中,和屏幕上的元素进行交互主要通过属性进行。在早期设计阶段,WPF的设计者决定创建一个更加强大的属性模型,该模型支持许多特性,例如,更改通知、默认值继承以及减少属性存储空间。该模型的最终结果就是依赖项属性(dependency property)特性,这一特性将在第4章中进行分析。通过继承自DependencyObject类,WPF类可以获得对依赖项属性的支持。
3. System.Windows.Media.Visual类
在WPF窗口中显示的每个元素,在本质上都是一个Visual对象。可以将Visual类看作是一个绘图对象,它封装了绘图指令、如何执行绘图的附加细节(如剪裁、透明度以及变换设置)以及基本功能(如命中测试)。Visual类还在托管的WPF库和渲染桌面的milcore.dll程序集之间提供了链接。任何继承自Visual的类都可以在窗口上被显示出来。如果更愿意使用轻量级的API创建用户界面,而不想使用WPF的高级框架特征,可使用在第14章中所描述的方法,直接对Visual对象进行编程。
4. System.Windows.UIElement类
UIElement类为WPF的本质特征提供支持,如布局、输入、焦点以及事件(WPF团队使用首字母缩写LIFE来表示)。例如,在这里定义两个步骤的测量和排列布局过程,这些内容将在第18章中介绍。在该类中,原始的鼠标单击和按键操作被转换为更有用的事件,如MouseEnter事件。与属性一样,WPF实现了一个增强的称为路由事件(routed event)的事件路由系统。在第5章中将学习路由事件它的工作原理。最后,在UIElement类中还添加了对命令的支持(第9章)。
5. System.Windows.FrameworkElement类
FrameworkElement类是WPF核心继承树中的最后一站。该类实现了一些全部由UIElement类定义的成员。例如,UIElement类为WPF布局系统设置了基础,但是FrameworkElement类提供了重要属性(如HorizontalAlignment属性和Margin属性)。UIElement类支持数据绑定、动画以及样式等核心特性。
6. System.Windows.Shapes.Shape类
基本的形状类(如Rectangle类、Polygon类、Ellipse类、Line类以及Path类)都继承自该类。这些形状类可以和更传统的Windows小组件一起使用,如按钮和文本框。在第12章将学习如何构建形状。
7. System.Windows.Controls.Control类
控件(control)是可以和用户进行交互的元素。控件显然包括TextBox控件、Button控件以及ListBox控件。Control类为设置字体和前景色与背景色提供了附加属性。但是令人最感兴趣的细节是模板支持,通过模板支持可以使用自定义风格的绘图替换控件的标准外观。将在第17章中学习控件模板。
注意:
在Windows窗体编程中,窗体中的所有可视化内容都被称为控件。在WPF中,不再如此。可视化内容被称为元素(element),只有部分元素是控件(控件是那些能够接收焦点并且能与用户进行交互的元素)。这一系统更加令人混淆之处在于,许多元素是在System.Windows.Controls名称空间中定义的,但它们不是继承自System.Windows.Controls.Control类,并且不被认为是控件。Panel类就是其中的一个例子。
8. System.Windows.Controls.ContentControl类
ContentControl类是所有具有单一内容的控件的基类。包括从简单的标签到窗口的所有内容。该模型给人印象最深刻的部分是:控件中的单一内容可以是从普通的字符串乃至具有其他形状和控件组合的布局面板(详见第6章)。
9. System.Windows.Controls.ItemsControl类
ItemsControl类是所有显示选项集合的控件的基类,如ListBox控件和TreeView控件。列表控件非常灵活—— 例如,使用ItemsControl类的内置特征,可以将简单的ListBox控件变换成单选按钮列表、复选框控件列表、平铺的图像或者是您所选择的完全不同的元素的组合。实际上,WPF中的菜单、工具栏以及状态栏都是特定的列表,并且实现它们的类都继承自ItemsContorl类。当在第19章中学习数据绑定时,将开始使用列表控件。在第22章中还将进一步学习列表控件,并且在第22章中还将学习更专业的列表控件。
10. System.Windows.Controls.Panel类
Panel类是所有布局容器的基类,布局容器是可以包含一个或多个子元素、并根据特定的规则对子元素进行排列的元素。这些容器是WPF布局系统的基础,并且使用它们是以最富有吸引力、最灵活的方式安排内容的关键。在第3章将详述WPF布局系统。
1.5 WPF 4
1.2.2 WPF的演化
尽管WPF是一种较新的技术。它是几个已经发布的.NET的一部分,并通过以下版本不断地进行增强:,但是现在已经有了如下两个版本:
● WPF 3.0。这是WPF的第一个版本,它和另两种新技术一起发布:Windows通信基础(Windows Communication Foundation,WCF)和Windows工作流基础(Windows Workflow Foundation,WF)。这三种新技术合称为.NET Framework 3.0(尽管.NET的核心部分没有改变)。
● WPF 3.5。一年后前,一个新版本的WPF作为.NET Framework3.5的一部分发布。新版本WPF的新特性主要是一些小的改进,包括。这些错误修复和性能改进的部分内容,通过.NET Framework 3.0 Service Pack1在.NET Framework 3.0中也可以使用。
● WPF 3.5 SP1。当.NET Framework Service Pack1(SP1)发布时,WPF设计人员利用该机会添加了一些新功能,例如平滑图形效果(通过像素着色器实现)以及高级的DataGrid控件。
● WPF 4。最新发布的WPF版本增加了大量的改进,包括一些基于已经存在的WPF基础结构构建的非常有价值的功能特征。其中最引人注意的一些修改包括更好的文本渲染、更自然的动画以及对Windows 7特性的支持,例如多点触控(multitouch)和新的任务栏。
1.5.1 1. WPF 3.5的新特性性
本书涵盖了WPF的所有概念,包括最时髦的新特性以及一成不变的核心原则。然而,如果您以前使用过WPF,请注意阅读每章引言之后的“新增功能(What`s New)”部分。该部分详细介绍了相对较新的内容——换句话说,是在WPF 3.5 SP1或WPF 4中增加的特性。如果某一章引言部分之后没有提供“新增功能What`s New”部分,就可以肯定该章介绍的WPF特性在最新发布的版本中没有发生变化。
也可以通过以下列表识别出自从WPF 3.0以来最值得注意的变化,同时可以了解到每个新特性性是在本书中的哪一章进行介绍的。
● 更多控件。WPF元素家族一直在保持着增长。它现在包含一个专业的DataGrid控件(第22章)、一个标准的DatePicker控件和Calendar控件(第6章),以及一个用于查看HTML和Wweb冲浪的本地WebBrowser控件(第24章),这些新控件可以为应用程序提供时髦的外观。
● 2D绘图改进。现在任何元素的可视化外观都能够通过像素着色器(使用最高版本为3的像素着色器标准)进行极大的改变,以得到PhotoShop风格的效果。希望通过手动控制单个像素的开发人员还可以使用WriteableBitmap类生成并修改图像。这些两个特性性将在第14章中介绍。
● 动画 缓动。通过这些函数可以创建自然地进行反弹、加速以及摆动的更加逼真的动画。这部分内容将在第15章中介绍。
● 可视化状态管理器。该特性是在Silverlight中第一次引入的,可视化状态管理器(第17章)提供了一种更换控件皮肤的更简单方法,使用这种方法不需要理解它们内部工作的复杂细节。
● Windows 7。Microsoft最新的操作系统增加了大量的新特性。WPF为重新设计拼凑的(revamped)任务栏提供了本地支持,通过该特性可以使用跳转转移列表(jump lists)、图标重叠、进度提示、以及工具栏缩略图(所有这些内容将在第23章中进行介绍)。并且,如果具有恰当的硬件,还可以使用WPF为Windows 7多点触控功能提供的支持(第15章),多点触控是在触摸屏上进行操作以控制可视化对象的能力。
● 更好的渲染。WPF继续改进显示质量,处理表现手法(idiosyncrasy)特异情况、以及因为使用分辨率无关绘图模型从而缩放可能会造成模糊的显示缩放问题。在WPF 4中,您可以使用布局旋转功能来确保布局容器与实际像素位置对齐,确保获得清晰的显示效果(见第3章)。这同样适用于渲染的文本,确保即使形状极小,也十分清晰。
● 位图缓存。在合适的情况下,可以通过在显存中缓存复杂的向量图形减少CPU的负担。当使用动画时,该技术特别方便,该技术将在第16章中进行介绍。
● XAML 2009。WPF引进了一个新版本的XAML标记标准,XAML用于在一个窗口或页面中声明用户界面。新版本的XAML提供了大量的小改进,但是您可能不会使用它们,因为该标准没有被构建进WPF XAML编译器。第2章提供了更多与这种情况相关的内容。
1.5.2 WPF 工具包
一个新控件在被集成进.NET平台的WPF库中之前,它通常先被放入一个称为WPF工具包(WPF Toolkit)的Microsoft下载中。但是WPF工具包不仅仅是一个预览WPF未来方向的地方——它还是一个非常好的实用使用组件和控件的源,从而在正常的WPF发布周期之外可以使用这些控件和组件。例如,WPF没有提供任何类型的制图工具,但是WPF工具包提供了一套控件用于创建柱状图、饼形图、气泡图、散点图以及线图形。
本书偶尔会引用WPF工具包,以指出在 核心.NET运行库中没有提供但是又非常有用的部分功能。为了下载WPF工具包、查看其代码或阅读其文档,导航浏览到网址。您还可以在那里找到连接指向到由Micorsoft托管的其他WPF项目的链接,包括WPF Futures未来(该项目提供了更多实验性的WPF特性)和WPF测试工具。
1.5.3 Visual Studio 2010
尽管可以手工或使用面向图形设计的工具Expression Blend构建WPF用户界面,但是大多数开发人员将从使用Visual Studio开始进行开发,并且大部分(或全部)时间用于使用Visual Studio进行开发。本书假定使用Visual Studio,并且偶尔会介绍如何使用Visual Stuio用户界面执行一个重要的任务,例如添加资源、配置项目属性以及创建控件库程序集。然而,不会花费大量时间研究Visual Studio的设计时技巧。反而,将集中研究创建专业应用程序所需要的底层标记和代码。
注意:
您可能已经知道了如何使用Visual Stuido创建WPF项目,但是在此还是快速概括一下。首先,选择File | New | Project菜单项。然后,(在左边的树种中)选择Visual C# | Windows组,然后(在右边的列表中)选择WPF Application模板。在第24章将学习更加专用的WPF Browser Application模板。一旦选择了一个目录,输入项目名称,并单击OK按钮,这时将得到一个WPF应用程序的基本框架。
12. 多目标
在过去,以前版本的Visual Studio的每个版本和只集成特定版本的.NET紧密耦合在一起。使用Visual Studio .NET2010没有这一限制——可以设计一个针对2.0到4.0之间的任何.NET版本的应用程序。
显然,并不能创建使用.NET 2.0的WPF应用程序,但是.NET 3.0和.NET 3.5都支持WPF创建.NET 1.0应用程序,使用Visual Studio .NET 2003创建.NET 1.1应用程序,以及使用Visual Studio 2005创建.NET 2.0应用程序。Visual Studio 2008突破了这一限制,它允许创建.NET 2.0、.NET 3.0或.NET 3.5应用程序。
显然,不可能使用.NET 2.0创建WPF应用程序,但是.NET 3.0和.NET 3.5都支持WPF。考虑到更广泛多的兼容性,可以选择.NET 3.0作为目标(因为.NET 3.0应用程序可以运行于.NET 3.0、和.NET 3.5以及4.0运行库之上)。或者,也可以选择.NET 3.5或4.0作为目标,以使用WPF或.NET平台中本身更新的特性(选择使用.NET 3.5通常是因为它支持LINQ,LINQ是一系列允许.NET语言使用高度集成的查询语法访问不同数据源的技术)。
当使用在Visual Studio中创建一个新的项目时(通过选择File | New | Project菜单项),可从New Project对话框上部紧挨着.NET Framework项目模板列表右上角的下拉列表框中选择.NET Framework的目标版本(如图1-4所示)。以后在任何时候,还可以通过在Solution Explorer中双击Properties节点,并改变Target Framework下拉列表中的选项来改变Framework的目标版本。
[pic]
图1-42 选择.NET Framework的目标版本
以后还可以随时通过在Solution Explorer中双击Properties节点,并通过改变Target Framework下拉列表中的选项来改变Framework的目标版本。
为了提供准确的多目标特征,Visual Studio 2010为每一版本的.NET都提供了参考程序集。这些程序集包括所有类型的元数据,但是不需要代码实现它。这意味着Visual Studio 2010可以使用参考程序集修补它的智能感知和错误检查,确保不能使用在设定的.NET版本中没有提供的控件、类以及成员程序。Visual Studio 2010还使用元数据确定在ToolBox中应当显示哪些控件、在Properties窗口和Object Browser中应当显示哪些成员等,保证整个IDE被限制于您选择的版本。
2. .NET客户端协议子集客户端配置
奇特的是,有两种方法用于定向到WPF 4。第一种选择是构建需要标准的安装整个.NET Framework 4标准安装的应用程序。第二种选择是构建需要.NET Framework 4 Client Profile客户端配置的应用程序。
客户端协议子集(client profile)配置(client profile)是类似WPF的富客户端应用程序所需要的.NET Framwork子集。它不包括服务器端功能特征,例如、调试器程序、开发人员工具、代码编译器以及遗留的功能(例如Oracle数据库支持)。更重要的是,客户端更小所以代码更小—— 需要约30MB的下载,而整个.NET Framework 4可重发布包最多需要100MB。当然,如果应用程序定向到.NET Framework 4 客户端Client Profile配置,并且客户端具有完整版本的.NET Framework,应用程序仍然能够正常运行。
客户端协议子集配置的概念是在.NET 3.5 SP1中引入的。然而,在那个发布版本中它仍然有几个问题,从而使其无法演化为标准。现在,在.NET 4中,Microsoft对客户端协议子集配置包含的特性集进行了调整,目标是使其成为每个应用程序的标准选择。在Visual Studio 2010中,大部分项目被自动定向到.NET Framework 4 Client Profile客户端配置(如果在New Project对话框中选择.NET Framework 4,实际上是定向到.NET Framework 4 Client Profile客户端配置)。如果在项目属性中更改变Target Framework设置,将看到更详细的列表,为.NET Framework 4(完整版)和.NET Framework 4 Client Profile客户端配置分别提供了相应的选项。
当确定了要定向到.NET的哪个版本时,考虑在多大范围内部署运行库通常同时是很重要的。在理想的情况下,用户应当能够运行应用程序,而不需要另外的下载和安装步骤。下面是一些指导原则,对于选择定向到哪个.NET版本可能会有所帮助。
● Windows Vista中包含了.NET Framework 3.0。
● Windows 7中包含了.NET Framework 3.5 SP1。
● 建议为Windows Vista和Windows 7(通过Windows 更新)更新.NET Framework 4 Client Profile客户端配置。对于Windows XP是可选的。
3. Visual Studio 设计器
尽管Visual Studio是WPF编程的重要工具,但是以前版本的Visual Studio在其功能上有一个很大的缺陷—— 它们没有为创建用户界面提供图形设计器。因此,开发人员只能手工编写XAML标记,或在Visual Studio和更加面向设计的Expression Blend之间进行切换。Visual Studio 2010最终解决了这个问题,提供了一个功能丰富的设计器用于创建WPF用户界面。
虽然Visual Studio 2010允许拖放WPF窗口,但是这并不意味着应当立即(或完全)使用Visual Studio创建用户界面。正如将在第3章中介绍的,WPF使用灵活的并且具有细微差别的布局模型,从而可以在用户界面中为确定元素的尺寸和位置使用不同的策略。为了得到所需要的结果,需要选择恰当适当的布局容器组合,适当地对其进行安排,并配置属性。Visual Studio可以帮助您完成该任务,但是如果首先学习基本的XAML标记以及WPF布局,该任务会更加容易。然后,就能够查看Visual Studio可视化设计器生成的标记,并且酌情手动修改这些标记。
一旦掌握了XAML的语法(第2章),并且学习了WPF的布局控件系列(第3章),对于选择如何创建窗口就足够了。有些专业开发人员使用Visual Studio,有些使用Expression Blend,有些手动编写XAML,而有些并结合使用这些方法(例如,手动创建基本的布局结构,然后使用Visual Studio设计器对其进行配置)。
1.64 小结
本章简要介绍了WPF及其作用。分析了WPF的底层体系结构,并简要介绍了核心类。
WPF是未来Windows开发的开端。最终,WPF将会变成一个类似User32和GDI/GDI+的系统,在它之上会增加更多增强的和高级的特征。最后,WPF将允许以使用Windows窗体所不可能(或者至少是不完全可能)的方式来设计应用程序。
显然,WPF引入了许多重要的变化。然而,有5条重要的准则更加突出,因为它们和以前的Windows用户界面工具包(如Windows窗体)的区别很大。这些准则如下:
● 硬件加速。所有的WPF绘图操作都是通过DirectX进行的,从而可以充分利用现代显卡的最新功能。
● 分辨率无关性。WPF能够根据系统DPI设置,非常灵活地放大和缩小显示的内容,以使其适合所使用的显示器和显示选择。
● 控件无固定外观。在传统的Windows开发中,在定制的符合需求的控件(这类控件是指自绘制的控件)和由操作系统渲染的并且实际上外观是固定的控件之间有很大的差别。在WPF中,从基本的Rectangle形状到标准的Button控件或更加复杂的Toolbar控件,都是使用相同的渲染引擎绘制的,并且都是完全可定制的。因此,WPF控件经常被称做无外观控件—— 它们为控件定义了功能,但是没有固定的“外观”。
● 声明式用户界面。在下一第2章将学习XAML,它是用于来定义WPF用户界面的标记标准。通过XAML创建窗口可以不用编写代码。特别是XAML的能力不局限于创建固定不变的用户界面。可以使用许多工具,如数据绑定和触发器等自动运行基本的用户界面行为(例如,当页面通过一个记录源时文本框更新它们自身,当鼠标移动到标签上时标签变亮),所有这些都不需要编写C#代码。
● 基于对象的绘图。即使准备在更低级的可视化层(而不是高级的元素层)上工作,也不需要使用绘图和像素进行工作,而是可以创建图形对象并让WPF尽可能最优化地显示出来。
全书都会运用这些原则。但在进一步分析这些原则之前,应当首先学习有关的补充标准。下一第2章将介绍XAML,它是用于定义WPF用户界面的标记语言。
-----------------------
WPF 概 述
第 1 章
................
................
In order to avoid copyright disputes, this page is only a partial summary.
To fulfill the demand for quickly locating and searching documents.
It is intelligent file search solution for home and business.