论文部分内容阅读
摘要:WPF以其丰富的界面表现力和功能扩展能力而备受瞩目,而作为其载体的控件开发一直是WPF开发的核心问题;本文从WPF控件的概念说起,逐层深入,从不同角度分析研究了WPF控件开发的相关问题。
关键词:WPF;控件;模板
中图分类号:TP391.41 文献标识码:A文章编号:1007-9599 (2011) 12-0000-02
WPF Control Development Study
Yang Fan
(CSIC,No.722 Institute,Information Networks Division,Wuhan430205,China)
Abstract:WPF interface for its rich expressive power and scalability features and highly anticipated,and as its carrier WPF control development has been the development of the core issues;this concept from the start with WPF controls,drill down,from a different angle analysis of the WPF control development related issues.
Keywords:WPF;Control;Template
WPF是Windows Presentation Foundation的简称,是微软推出的新一代GUI开发工具,专注于程序表示层的实现,具有优异的复用和扩展能力,丰富的界面元素支持以及良好的表示层与数据逻辑的低耦合性。WPF之所以能称得上是新一代GUI的关键在于:一,具有专门用于UI设计的XAML语言;二,引入了数据驱动界面的概念,让数据重归核心地位。作为实现这两项关键技术的载体,WPF的控件尤其值得研究。
一、WPF控件概念研究
(一)什么是控件
WPF把能够展示数据、响应用户操作的UI元素称为控件(Control)。控件所展示的数据,叫数据内容,控件在响应用户操作后执行方法或以事件通知应用程序的过程,叫行为或算法内容。可见,WPF中的控件具有双重角色,是个抽象的概念:控件是数据和行为的载体,而无固定的形象(形象可以通过模板按需任意更换)。
一个控件的外观由其算法内容和数据内容决定。算法内容是指控件的功能,如能展示的数据,具有的方法,响应的操作,激发的事件等等,它们是一组相关的算法逻辑;数据内容是指控件所展示的具体数据。
(二)WPF控件框架
图:WPF控件类派生关系
WPF标准控件的派生关系如上图所示,以按钮控件为例,属于内容控件,只能容纳一个其他控件或布局控件作为其内容,其父类为Content Control;又如布局控件Grid,属于布局控件,继承自Panel类,可以容纳多个控件或嵌套其他布局控件。
(三)WPF控件的树形结构
如果把WPF控件比作一个容器,容器的内容则可以是数据,也可以是控件。当控件的内容还是控件的时候就形成了控件的嵌套。这种控件嵌套在WPF的UI布局中是非常常见的。正因为允许嵌套,所以WPF的UI会形成一个树形结构。
如果不考虑控件内部的组成结构,只观察由控件组成的树,则这棵树称为“逻辑树”(Logical Tree);WPF控件本身往往是有更基本的控件构成,即控件本身就是一颗树;如果考虑控件内部树在内的全部UI结构,则称这棵树为“可视元素树”(Visual Tree)。仍以按钮控件为例,如果在按钮控件内包含一个按钮控件,再在子按钮控件内再包含一个按钮控件,依此类推就可以在UI上绘制一个多层嵌套的按钮控件,每一个外层按钮内都包含一个按钮;更实用的例子则是各种布局控件,其根据需要内部层层嵌套控件和其他布局控件。
二、WPF控件设计策略
(一)资源(Resource)
在WPF中,每一个界面元素都包含一个Resource属性,其引用源是类型为Resource Dictionary的以“键-值”对的形式存储的资源。资源是承载样式和各种模板的载体,在资源中定义的各种样式和模板可以直接在各个界面元素中指定使用。
(二)样式(Style)
样式可以理解为一组展示控件属性的集合。通过采用样式,可以创建一套可重用的显示效果以及控件行为,套用样式同样可以避免重写控件。例如,设计者希望Text Block控件采用蓝色的12号Arial字体,可以将该样式作为资源写入程序,并在该样式内根据需要设定好相应的控件属性。之后,每当需要将指定的Text Block控件设置成该样式时,设置其Style属性指向该样式即可。
(三)模板(Template)
WPF的每一个控件都有一个默认的模板,该模板描述了控件的外观以及外观对外界刺激所做出的反应。我们可以自定义一个模板来替换掉控件的默认模板以便打造个性化的控件。以往的GUI技术中,控件的算法内容和数据内容都是固定的,但在WPF中,通过模板将数据和算法解耦了,并由此将WPF的模板分为两类:控件模板与数据模板。
1.控件模板(Control Template)
控件模板是算法内容的表现形式。控件模板与Style不同,Style只能改变控件的已有属性值(比如颜色字体)来定制控件,但控件模板可以改变控件的内部结构(Visual Tree)来完成更为复杂的定制。例如,WPF中的Check Box与其基类Toggle Button在功能上几乎完全一样,但外观区别却很大,就是替换了Control Template的结果。要替换控件的模板,我们只需要声明一个Control Template对象,并对该Control Template对象做相应的配置,然后将该Control Template对象赋值给控件的Template属性即可。
2.数据模板(Data Template)
数据模板是数据内容的表现形式,实现表现形式与逻辑的分离。数据模板允许自定义数据内容如何显示,且模板本身可以包含界面元素。除界面显示外,在数据模板中还可以应用WPF核心技术之一的绑定技术动态绑定模板内定义的控件,以此方便的将事件驱动模式升级为数据驱动模式,在剥离界面与逻辑处理的同时,极大地简化了后台代码的编写量。
3.数据模板与控件模板的关系
WPF中的控件包括控件本身以及其所包含的内容两个部分,对模板来说,控件模板的作用范围就在控件本身(包括内容区域);而数据模板则专注于该控件所包含的内容,它可以是一个单独的子控件,也可以是一个包含复杂结构的子容器。用集合图描述就是:数据模板的作用范围是控件模板作用范围的子集。
三、WPF控件设计的模型
在WPF中,提供了三种层次上的自定义控件方法,每一种都提供了一组不同的特性以满足不同级别的复杂度。三种模型依次为:User Control,Control和Framework Element。
(一)继承用户控件(User Control)
以继承用户控件的方式来实现自定义控件时,设计者可以再其中添加现有组件(包括已经定义的其他自定义控件),并可根据需要引用事件处理。设计合理的话,一个用户控件可以很好的受益于Rich Content、样式和触发器提供的便利。但此类控件无法通过数据模板和控件模板定制界面。从项目开发实际上来看,现有的WPF控件具有的控件和数据模板一般足以满足项目需求,此种自定义方法是最为常用和实用的,即便是较复杂的需求也可以通过嵌套实现的用户控件来完成。
(二)继承一般控件(Control)
大多数WPF现有控件都是从Control类继承而来的。创建这类控件时,是通过模板来定义其界面显示以及数据交互方式的。通过使用命令对象和绑定技术替代事件处理方式可以进一步降低界面和操作逻辑的耦合度,并且可以避免在控件模板中引用界面元素。控件的使用者可以通过重新自定义控件模板的方式来改变控件的自有行为,比如显示数据、执行方法、激发事件等。当然这样的设计方式比从用户控件继承要复杂,但也供了更大的设计控件和灵活性。
(三)继承框架元素(Framework Element)
从用户控件或者一般控件继承的设计方式都要依赖于组合一些现有界面元素,但很多时候一个控件的外观不仅仅是一些简单元素的复合。在这种情况下,基于框架元素的设计就是合理的选择了。
设计基于框架元素的组件时有两种标准方法:直接渲染和复合自定义元素。直接渲染包括重载Framework Element的On Render方法和提供Drawing Context操作来显示定义控件的外观。WPF中的Image和Border控件用的就是这种方法。复合自定义元素包括使用一些类型为Visual的对象累组合出控件外观。WPF中的Track控件就是采用的这个方法。当然,在一个控件中混合使用这两种方法也是可行的。
四、结束语
根据笔者开发实际和学习总结,学习WPF,不仅仅要掌握各种控件的使用方法,更重要的是通过尝试自定义复杂控件来学习WPF的编程思想,其层次化的高可重用性架构以及优秀的低耦合界面与逻辑实现思路很值得学习和研究。相信随着WPF控件的丰富化和规范化,WPF的功能必将更加丰富多彩,其生命力也值得期待。
参考文献:
[1]Chris Anderson.WPF核心技术Essential Windows Presentaion Foundation[J].人民邮电出版社,2009
[2]刘铁猛.深入浅出WPF[J].水利水电出版社,2010
[3]李应保.WPF专业编程指南[J].电子工业出版社,2010
关键词:WPF;控件;模板
中图分类号:TP391.41 文献标识码:A文章编号:1007-9599 (2011) 12-0000-02
WPF Control Development Study
Yang Fan
(CSIC,No.722 Institute,Information Networks Division,Wuhan430205,China)
Abstract:WPF interface for its rich expressive power and scalability features and highly anticipated,and as its carrier WPF control development has been the development of the core issues;this concept from the start with WPF controls,drill down,from a different angle analysis of the WPF control development related issues.
Keywords:WPF;Control;Template
WPF是Windows Presentation Foundation的简称,是微软推出的新一代GUI开发工具,专注于程序表示层的实现,具有优异的复用和扩展能力,丰富的界面元素支持以及良好的表示层与数据逻辑的低耦合性。WPF之所以能称得上是新一代GUI的关键在于:一,具有专门用于UI设计的XAML语言;二,引入了数据驱动界面的概念,让数据重归核心地位。作为实现这两项关键技术的载体,WPF的控件尤其值得研究。
一、WPF控件概念研究
(一)什么是控件
WPF把能够展示数据、响应用户操作的UI元素称为控件(Control)。控件所展示的数据,叫数据内容,控件在响应用户操作后执行方法或以事件通知应用程序的过程,叫行为或算法内容。可见,WPF中的控件具有双重角色,是个抽象的概念:控件是数据和行为的载体,而无固定的形象(形象可以通过模板按需任意更换)。
一个控件的外观由其算法内容和数据内容决定。算法内容是指控件的功能,如能展示的数据,具有的方法,响应的操作,激发的事件等等,它们是一组相关的算法逻辑;数据内容是指控件所展示的具体数据。
(二)WPF控件框架
图:WPF控件类派生关系
WPF标准控件的派生关系如上图所示,以按钮控件为例,属于内容控件,只能容纳一个其他控件或布局控件作为其内容,其父类为Content Control;又如布局控件Grid,属于布局控件,继承自Panel类,可以容纳多个控件或嵌套其他布局控件。
(三)WPF控件的树形结构
如果把WPF控件比作一个容器,容器的内容则可以是数据,也可以是控件。当控件的内容还是控件的时候就形成了控件的嵌套。这种控件嵌套在WPF的UI布局中是非常常见的。正因为允许嵌套,所以WPF的UI会形成一个树形结构。
如果不考虑控件内部的组成结构,只观察由控件组成的树,则这棵树称为“逻辑树”(Logical Tree);WPF控件本身往往是有更基本的控件构成,即控件本身就是一颗树;如果考虑控件内部树在内的全部UI结构,则称这棵树为“可视元素树”(Visual Tree)。仍以按钮控件为例,如果在按钮控件内包含一个按钮控件,再在子按钮控件内再包含一个按钮控件,依此类推就可以在UI上绘制一个多层嵌套的按钮控件,每一个外层按钮内都包含一个按钮;更实用的例子则是各种布局控件,其根据需要内部层层嵌套控件和其他布局控件。
二、WPF控件设计策略
(一)资源(Resource)
在WPF中,每一个界面元素都包含一个Resource属性,其引用源是类型为Resource Dictionary的以“键-值”对的形式存储的资源。资源是承载样式和各种模板的载体,在资源中定义的各种样式和模板可以直接在各个界面元素中指定使用。
(二)样式(Style)
样式可以理解为一组展示控件属性的集合。通过采用样式,可以创建一套可重用的显示效果以及控件行为,套用样式同样可以避免重写控件。例如,设计者希望Text Block控件采用蓝色的12号Arial字体,可以将该样式作为资源写入程序,并在该样式内根据需要设定好相应的控件属性。之后,每当需要将指定的Text Block控件设置成该样式时,设置其Style属性指向该样式即可。
(三)模板(Template)
WPF的每一个控件都有一个默认的模板,该模板描述了控件的外观以及外观对外界刺激所做出的反应。我们可以自定义一个模板来替换掉控件的默认模板以便打造个性化的控件。以往的GUI技术中,控件的算法内容和数据内容都是固定的,但在WPF中,通过模板将数据和算法解耦了,并由此将WPF的模板分为两类:控件模板与数据模板。
1.控件模板(Control Template)
控件模板是算法内容的表现形式。控件模板与Style不同,Style只能改变控件的已有属性值(比如颜色字体)来定制控件,但控件模板可以改变控件的内部结构(Visual Tree)来完成更为复杂的定制。例如,WPF中的Check Box与其基类Toggle Button在功能上几乎完全一样,但外观区别却很大,就是替换了Control Template的结果。要替换控件的模板,我们只需要声明一个Control Template对象,并对该Control Template对象做相应的配置,然后将该Control Template对象赋值给控件的Template属性即可。
2.数据模板(Data Template)
数据模板是数据内容的表现形式,实现表现形式与逻辑的分离。数据模板允许自定义数据内容如何显示,且模板本身可以包含界面元素。除界面显示外,在数据模板中还可以应用WPF核心技术之一的绑定技术动态绑定模板内定义的控件,以此方便的将事件驱动模式升级为数据驱动模式,在剥离界面与逻辑处理的同时,极大地简化了后台代码的编写量。
3.数据模板与控件模板的关系
WPF中的控件包括控件本身以及其所包含的内容两个部分,对模板来说,控件模板的作用范围就在控件本身(包括内容区域);而数据模板则专注于该控件所包含的内容,它可以是一个单独的子控件,也可以是一个包含复杂结构的子容器。用集合图描述就是:数据模板的作用范围是控件模板作用范围的子集。
三、WPF控件设计的模型
在WPF中,提供了三种层次上的自定义控件方法,每一种都提供了一组不同的特性以满足不同级别的复杂度。三种模型依次为:User Control,Control和Framework Element。
(一)继承用户控件(User Control)
以继承用户控件的方式来实现自定义控件时,设计者可以再其中添加现有组件(包括已经定义的其他自定义控件),并可根据需要引用事件处理。设计合理的话,一个用户控件可以很好的受益于Rich Content、样式和触发器提供的便利。但此类控件无法通过数据模板和控件模板定制界面。从项目开发实际上来看,现有的WPF控件具有的控件和数据模板一般足以满足项目需求,此种自定义方法是最为常用和实用的,即便是较复杂的需求也可以通过嵌套实现的用户控件来完成。
(二)继承一般控件(Control)
大多数WPF现有控件都是从Control类继承而来的。创建这类控件时,是通过模板来定义其界面显示以及数据交互方式的。通过使用命令对象和绑定技术替代事件处理方式可以进一步降低界面和操作逻辑的耦合度,并且可以避免在控件模板中引用界面元素。控件的使用者可以通过重新自定义控件模板的方式来改变控件的自有行为,比如显示数据、执行方法、激发事件等。当然这样的设计方式比从用户控件继承要复杂,但也供了更大的设计控件和灵活性。
(三)继承框架元素(Framework Element)
从用户控件或者一般控件继承的设计方式都要依赖于组合一些现有界面元素,但很多时候一个控件的外观不仅仅是一些简单元素的复合。在这种情况下,基于框架元素的设计就是合理的选择了。
设计基于框架元素的组件时有两种标准方法:直接渲染和复合自定义元素。直接渲染包括重载Framework Element的On Render方法和提供Drawing Context操作来显示定义控件的外观。WPF中的Image和Border控件用的就是这种方法。复合自定义元素包括使用一些类型为Visual的对象累组合出控件外观。WPF中的Track控件就是采用的这个方法。当然,在一个控件中混合使用这两种方法也是可行的。
四、结束语
根据笔者开发实际和学习总结,学习WPF,不仅仅要掌握各种控件的使用方法,更重要的是通过尝试自定义复杂控件来学习WPF的编程思想,其层次化的高可重用性架构以及优秀的低耦合界面与逻辑实现思路很值得学习和研究。相信随着WPF控件的丰富化和规范化,WPF的功能必将更加丰富多彩,其生命力也值得期待。
参考文献:
[1]Chris Anderson.WPF核心技术Essential Windows Presentaion Foundation[J].人民邮电出版社,2009
[2]刘铁猛.深入浅出WPF[J].水利水电出版社,2010
[3]李应保.WPF专业编程指南[J].电子工业出版社,2010