c#2005net30高级编程(第5版)第31章Windows Presentati.doc_第1页
c#2005net30高级编程(第5版)第31章Windows Presentati.doc_第2页
c#2005net30高级编程(第5版)第31章Windows Presentati.doc_第3页
c#2005net30高级编程(第5版)第31章Windows Presentati.doc_第4页
c#2005net30高级编程(第5版)第31章Windows Presentati.doc_第5页
已阅读5页,还剩71页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第31章 Windows Presentation Foundation310第 章 Windows Presentation FoundationWindows Presentation Foundation(WPF)是.NET Framework 3.0中的三个主要扩展之一。WPF是为智能客户应用程序创建UI的一个新库。Windows窗体控件基于Windows内置控件,利用了基于屏幕像素的Windows句柄。WPF基于DirectX。应用程序不再使用Windows句柄,更便于重新设置UI的大小,并内置了音频和视频的支持。本章的主要论题如下: WPF概述 用作基本绘图元素的图形 WPF控件及其特性 如何用WPF面板定义布局 WPF事件处理机制 样式、模板和资源 如何创建动画 WPF数据绑定特性 Windows窗体集成提示:本章需要安装.NET Framework 3.0和.NET Framework 3.0 Extensions for Visual Studio 2005。31.1 概述WPF的一个主要特性是设计人员和开发人员的工作很容易分开。设计人员的工作成果可以直接供开发人员使用。为此,必须理解XAML。本章的第一个主题是概述WPF,理解XAML的规则,讨论设计人员和开发人员如何合作。WPF由几个包含了上千个类的程序集组成。因此用户可以在这些类中浏览,查找需要的类,大致了解WPF中的类层次结构和命名空间。31.1.1 XAMLXML for Applications Markup Language(XAML)是一种XML语法,用于定义用户界面的层次结构。在下面的代码行中,声明了一个内容为Click Me!、名为button1的按钮。元素指定使用Button类:Click Me!提示:XAML元素总是有一个.NET类。在特性和子元素中,可以设置属性的值,定义事件的处理程序方法。为了测试简单的XAML代码,可以启动实用工具XAMLPad.exe(参见图31-1),在编辑字段中输入XAML代码。在XAMLPad中,可以在已准备好的和元素中编写元素。利用XAMLPad可以立即查看XAML结果。图 31-1XAML代码可以由WPF运行库解释,也可以编译为BAML(Binary Applications Markup Language),在默认情况下,这是由Visual Studio WPF项目完成的。BAML添加为可执行文件的一个资源。除了编写XAML之外,也可以用C#代码创建按钮。我们可以创建一个正常的C#控制台应用程序,添加对程序集WindowsBase、PresentationCore和PresentationFramework的引用,再编写下面的代码。在Main()方法中,从System.Windows命名空间中创建一个Window对象,设置Title属性。接着从System.Windows.Controls命名空间中创建一个Button对象,设置Content属性,将窗口的Content属性设置为该按钮。Application类的Run()方法负责处理Windows消息。using System;using System.Windows;using System.Windows.Controls;namespace Wrox.ProCSharp.WPFclass Program STAThreadstatic void Main()Window mainWindow = new Window();mainWindow.Title = WPF Application;Button button1 = new Button();button1.Content = Click Me!;mainWindow.Content = button1;Application app = new Application();app.Run(mainWindow);提示:Application类也可以用XAML定义。在Visual Studio WPF项目中,打开App.xaml文件,它包含Application类的属性和StartupUri。运行应用程序,会得到一个包含按钮的窗口,如图31-2所示。图 31-2可以看出,WPF的编程非常类似于Window窗体的编程,其区别是按钮有Content属性,而不是Text属性。但是,与通过代码创建UI窗体相比,XAML有一些非常好的优点。利用XAML,设计人员和开发人员可以更好地合作。设计人员可以用XAML代码设计一个漂亮的UI,开发人员在使用C#在后台代码中添加功能。使用XAML更便于将UI与功能分开。使用后台代码和XAML,可以直接与用XAML定义的元素交互操作。只需为该元素定义名称,将该名称用作变量,来修改属性,调用方法。按钮有一个Content属性,而不是Text属性,因为按钮可以显示任意信息。可以给按钮添加文本、图形、列表框、视频 等任何元素。1. 将属性用作特性在使用XAML之前,需要了解XAML语法的重要特性。使用XML特性可以指定类的属性。下面的例子说明了如何设置Button类的Content和Background属性。2. 将属性用作元素除了使用XML特性之外,属性也可以指定为子元素。指定Button元素的子元素,就可以直接设置Content的值。对于Button的其他属性,子元素名用外部元素的名称定义,之后是属性名:LightGreenClick Me!在上面的例子中,不一定要使用子元素;使用XML特性,也可以得到相同的结果。但是,如果特性值比字符串还复杂,就不能再使用特性了。例如,背景不仅可以设置为一种简单的颜色,还可以设置为笔刷,如设置为线性渐变笔刷:Click Me!3. 依赖属性在用WPF编程时,常常会遇到“依赖属性”这个术语。WPF元素是带有方法、属性和事件的类。WPF元素的几乎每个属性都是依赖属性,这是什么意思?依赖属性可以依赖其他输入,例如主题和用户喜好。依赖属性与数据绑定、动画、资源和样式一起使用。从编程的角度来看,要读写依赖属性,可以调用强类型化的属性,也可以给方法传送依赖属性对象。只有派生自DependencyObject基类的类才能包含依赖属性。下面的类MyDependency- Object定义了依赖属性SomeState。SomeStateProperty是DependencyProperty类型的一个静态字段,它支持依赖属性。依赖属性使用Register()方法通过WPF依赖属性系统来注册。Register()方法可以获取依赖属性的名称、依赖属性的类型和拥有者的类型。使用DependencyObject基类的SetValue()方法,可以设置依赖属性的值。使用GetValue()方法可以获取其值。依赖属性常常还有强类型化的访问权限。除了使用DependencyObject基类的方法之外,类MyDependencyObject还包含属性SomeState,它从set和get存取器的实现代码中调用SetValue()和GetValue()方法。public class MyDependencyObject : DependencyObjectpublic static readonly DependencyProperty SomeStateProperty =DependencyProperty.Register(SomeState, typeof(String), typeof(MyDependencyObject);public string SomeStateget return (string)this.GetValue(SomeStateProperty); set this.SetValue(SomeStateProperty, value); 提示:在WPF中,类DependencyObject位于层次结构的最高层。每个WPF元素都派生自这个基类。4. 附带属性WPF元素也可以从父元素中获得特性。例如,如果Button元素位于Canvas元素中,按钮的Top和Left属性把父元素的名称作为前缀。这种属性称为附带属性:Click Me!在后台代码中编写相同的功能有点不同,因为Button类没有Canvas.Top和Canvas.Left属性,但它包含在Canvas类中。设置所有类都有的附带属性有一个命名模式。支持附带属性的类有静态方法Set和Get,其中第一个参数是应用属性值的对象。Canvas类定义了静态方法SetLeft()和SetTop(),它们会获得与前面XAML代码相同的结果:STAThreadstatic void Main()Window mainWindow = new Window();Canvas canvas = new Canvas(); mainWindow.Content = canvas;Button button1 = new Button();canvas.Children.Add(button1);button1.Content = Click Me!;Canvas.SetLeft(button1, 40);Canvas.SetTop(button1, 30);Application app = new Application();app.Run(mainWindow);提示:附带属性可以实现为依赖对象。方法DependencyProperty.RegisterAttached()会注册附带属性。5. 标记扩展在为元素设置值时,可以直接设置值,但有时标记扩展非常有帮助。标记扩展包含花括号,其后是定义了标记扩展类型的字符串标志。下面是一个StaticResource标记扩展:除了使用标记扩展之外,还可以使用子元素编写相同功能的代码:Click Me!标记扩展主要用于访问资源和数据绑定,本章后面将讨论这两个主题。31.1.2 设计人员和开发人员的合作Windows应用程序的设计常常直接由开发人员完成。尤其是应用程序仅用于内部使用,就更是如此。如果雇用懂得UI设计技巧的人来设计UI,开发人员通常会得到设计人员的一个JPG文件,该文件描述了UI的外观。接着开发人员就要试图实现设计人员的规划。设计人员的一个简单修改,如给列表框和按钮指定不同的外观,就需要开发人员投入大量的精力设计定制的控件。因此,开发人员设计的UI与最初的设计大相径庭。WPF改变了这种情况。设计人员和开发人员可以使用相同的XAML代码。设计人员可以使用Expression Interactive Designer(EID)工具,开发人员则使用Visual Studio 2005,但他们可以用同一个项目文件工作。在这个合作过程中,设计人员使用与Visual Studio中相同的项目文件在EID中启动一个项目,接着,开发人员编写后台代码,同时设计人员改进UI。在开发人员改进功能的同时,设计人员还可以利用开发人员提供的功能,添加新的UI特性。当然,还可以用Visual Studio启动应用程序,以后再用EID改进UI。只是要小心,不要像处理Windows窗体那样设计UI,因为这没有充分利用WPF。图31-3显示了用WPF创建的Expression Interactive Designer。在这个应用程序中,工作区域和文档都是可以缩放的,因为WPF基于矢量图。图 31-3提示:比较EID和Visual Studio扩展,EID的优秀特性有定义样式、创建动画、使用图形等。为了合作,EID可以使用开发人员编写的后台编码类,设计人员可以在WPF元素中指定与.NET类的数据绑定。设计人员还可以在EID中启动完整的应用程序,来测试它。因为EID使用与Visual Studio相同的MS-Build文件,所以能编译后台编码的C#代码,运行应用程序。31.1.3 类层次结构WPF包含上千个类,有很深的层次结构。为了帮助理解类之间的关系,图31-4在一个类图中列出了一些WPF类。表31-1描述了一些类及其功能。图 31-4表 31-1类说 明DispatcherObjectDispatcherObject是一个抽象基类,用于绑定到一个线程上的类。与Windows窗体类似,WPF也要求仅从创建线程中调用方法和属性。派生自DispatcherObject的类有一个关联的Dispatcher对象,它可以用于切换线程Application在WPF应用程序中,会创建Application类的一个实例。这个类实现了Singleton模式,用于访问应用程序的窗口、资源和属性DependencyObjectDependencyObject是所有支持依赖属性的类的基类。依赖属性如前所述Visual所有可见元素的基类是Visual。这个类包含点击测试和传输等特性UIElement所有需要基本显示功能的WPF元素的抽象基类是UIElement。这个类提供了鼠标移动、拖放、按键的通道和起泡事件;提供了可以由派生类重写的虚显示方法;以及布局方法。WPF不再使用Window句柄,这个类就可以用作Window句柄(续表) 类说 明FrameworkElementFrameworkElement派生自基类UIElement,实现了由基类定义的方法的默认代码ShapeShape是所有图形元素的基类,例如Line、Ellipse、Polygon、RectangleControlControl派生自FrameworkElement,是所有用户交互元素的基类PanelPanel派生自FrameworkElement,是所有面板的抽象基类,这个类的Children属性用于面板中的所有UI元素,定义了安排子控件的方法。派生自Panel的类为子控件的布置方式定义了不同的类,例如WrapPanel、StackPanel、Canvas、GridContentControlContentControl是所有有单个内容的控件的基类,如Label、Button。内容控件的默认样式是受限制的,但可以使用模板改变其外观可以看出,WPF类有非常深的层次结构。本章将介绍提供核心功能的类,但不可能用一章的篇幅涵盖WPF的所有特性。31.1.4 命名空间Windows窗体类和WPF类很容易混淆。Windows窗体类位于System.Windows.Forms命名空间,而WPF类位于System.Windows命名空间及其子命名空间中,但不位于System.Windows. Forms命名空间。Windows窗体的Button类的全称是System.Windows. Forms.Button,而用于WPF的Button类的全称是System.Windows.Controls. Button。提示:Windows窗体详见第28和29章。WPF的命名空间及其功能如表31-2所述。表 31-2命 名 空 间 说 明System.Windows这是WPF的核心命名空间,其中包含WPF的核心类,如Application类、用于依赖对象的类、DependencyObject和DependencyProperty,所有WPF元素的基类FrameworkElementSystem.Windows.Annotations这个命名空间中的类用于用户在应用程序数据上创建的标识和记录,它们与文档分开存储。命名空间System.Windows.Annotations.Storage包含了存储标识的类System.Windows.AutomationSystem.Windows.Automation命名空间用于自动完成WPF应用程序。它有几个子命名空间。System.Windows.Automation.Peers命名空间包含用于自动化的WPF元素,如ButtonAutomationPeer和CheckBoxAutomationPeer。如果创建定制的自动化提供程序,就需要System.Windows.Automation. Provider命名空间。(续表) 命 名 空 间说 明System.Windows.Controls这个命名空间包含了所有WPF控件,如Button、Border、Canvas、ComboBox、Expander、Slider、ToolTip、TreeView等。在命名空间System.Windows.Controls.Primitives中,包含了在复杂控件中使用的类,如Popup、ScrollBar、StatusBar、TabPanel等System.Windows.Converters这个命名空间包含了用于数据转换的类。但它没有包含所有的转换类。核心转换类在System.Windows命名空间中定义System.Windows.Data这个命名空间由WPF数据绑定使用。其中的一个重要类是Binding,它用于定义WPF目标元素和CLR源之间的绑定System.Windows.Documents在处理文档时,可以使用这个命名空间中的许多类。内容元素FixedDocument和FlowDocument可以包含这个命名空间中的其他元素。System.Windows.Documents.Serialization命名空间中的类可以将文档写入磁盘System.Windows.InkWindows Tablet PC和Ultra Mobile PC使用得越来越多。在这些PC上,ink可以用于用户输入。System.Windows.Ink命名空间包含处理ink输入的类System.Windows.Input这个命名空间包含的几个类用于命令处理、键盘输入、使用触针等System.Windows.Interop这个命名空间中的类用于集成Win32和WPFSystem.Windows.Markup用于XAML标记代码的类位于这个命名空间System.Windows.Media要使用图像、音频和视频内容,可以使用这个命名空间中的类System.Windows.Navigation这个命名空间包含在窗口之间导航的类System.Windows.Resources这个命名空间包含资源的支持类System.Windows.ShapesUI的核心类位于这个命名空间,如Line、Ellipse、Rectangle等System.Windows.ThreadingWPF元素类似于绑定到单个线程上的Windows窗体控件。这个命名空间中的类可以处理多个线程,例如Dispatcher类就属于这个命名空间System.Windows.XpsXML Paper Specification(XPS)是一个新的文档规范,Microsoft Word也支持该规范。在System.Windows.Xps、System.Windows.Xps.Packaging和System.Windows.Xps.Serialization命名空间中,包含了创建和传送XPS文档的类31.2 形状形状是WPF的核心元素。利用形状,可以绘制矩形、线条、椭圆、路径、多边形和多义线等二维图形,这些图形用派生自抽象类Shape的类表示。图形在System.Windows. Shapes命名空间中定义。下面的XAML示例绘制了一个带腿的黄色笑脸,它用一个椭圆表示笑脸,两个椭圆表示眼睛,一个路径表示嘴,四个线条表示腿:图31-5显示了这些XAML代码的结果。因为这些图形都是基于矢量的,所以可以重新设置其大小。下面的代码指定了缩放比例为2,在图31-6中,图形增大了2倍。 图 31-5 图 31-6无论是按钮还是线条、矩形等图形,所有这些WPF元素都可以通过编程来访问。把Path元素的Name属性设置为mouth,就可以用变量名mouth以编程方式访问这个元素:在Path元素的后台编码属性Data中,mouth设置为一个新的图形。为了设置路径,Path类支持PathGeometry和路径标记语法。字母M定义了路径的起点,字母Q指定了二次贝塞尔曲线的一个控制点和终点。运行应用程序,会看到如图31-7所示的窗口。public Window1()InitializeComponent();mouth.Data = Geometry.Parse(M 62,125 Q 95,122 102,128);图 31-7在本章的前面提到,按钮可以包含任何内容。对XAML代码做一点儿修改,将Button元素作为内容添加到窗口中,会使图形显示在按钮中,如图31-8所示。图 31-8表31-3描述了System.Windows.Shapes命名空间中的图形。表 31-3Shape类说 明Line可以在坐标X1,Y1到X2,Y2之间绘制一条线Rectangle使用Rectangle类,可以指定Width和Height,绘制一个矩形Ellipse使用Ellipse类,可以绘制一个椭圆Path使用Path类可以绘制一系列直线和曲线。Data属性是Geometry类型。还可以使用派生自基类Geometry的类绘制图形,或使用路径标记语法来定义图形Polygon使用Polygon类可以绘制由线段连接而成的封闭图形。多边形由一系列赋予Points属性的Point对象定义PolyLine类似于Polygon类,使用PolyLine也可以绘制连接起来的线段,与多边形的区别是多义线不需要是封闭图形31.3 控件可以给WPF使用上百个控件。为了更好地理解它们,我们把控件分为如下类别: 简单控件 内容控件 有标题的内容控件 项控件 有标题的项控件31.3.1 简单控件简单控件是没有Content属性的控件。例如,Button类可以包含任意图形、任意元素,这对于简单控件而言没有问题。表31-4列出了简单控件及其功能。表 31-4简 单 控 件说 明PasswordBoxPasswordBox控件用于输入密码。这个控件有用于输入密码的特殊属性,例如PasswordChar定义了在用户输入密码时显示的字符,Password可以访问输入的密码。PasswordChanged事件在修改密码时调用ScrollBarScrollBar控件包含一个Thumb,用户可以在Thumb中选择一个值。如果文档在屏幕中放不下,就可以使用滚动条。一些控件包含滚动条,如果内容过多,就显示滚动条ProgressBar使用ProgressBar控件,可以指示某个时间较长的操作的进度Slider使用Slider控件,用户可以移动Thumb,选择一个范围的值。ScrollBar、ProgressBar和Slider派生自同一个基类RangeBaseTextboxTextbox控件用于显示简单的无格式文本RichTextboxRichTextbox控件通过FlowDocument类支持带格式的文本。RichTextBox和TextBox派生自同一个基类TextBoxBase 提示:尽管简单控件没有Content属性,但通过定义模板,完全可以定制这些控件的外观。模板详见本章后面的内容。31.3.2 内容控件ContentControl有Content属性,利用Content属性,可以给控件添加任意内容。Button类派生自基类ContentControl,所以可以在这个控件中添加任意内容。在上面的例子中,Button中有一个Canvas控件。表31-5列出了内容控件。表 31-5ContentControl控件说 明ButtonRepeatButtonToggleButtonCheckBoxRadioButton类Button、RepeatButton、ToggleButton和GridViewColumnHeader派生自同一个基类ButtonBase。所有这些按钮都响应Click事件。RepeatButton会重复响应Click事件,直到释放按钮为止ToggleButton是CheckBox和RadioButton的基类。这些按钮有开关状态。CheckBox可以由用户选择和取消选择,RadioButton可以由用户选择。清除RadioButton的选择必须通过编程来实现LabelLabel类表示控件的文本标签。这个类也支持访问键,例如菜单命令FrameFrame控件支持导航。使用Navigate()方法可以导航到一个页面内容上。如果该内容是一个网页,就使用浏览器控件来显示(续表) ContentControl控件说 明ListBoxItemListBoxItem是ListBox控件中的一项StatusBarItemStatusBarItem是StatusBar控件中的一项ScrollViewerScrollViewer是一个包含滚动条的内容控件,可以把任意内容放入这个控件,滚动条会在需要时显示ToolTipToolTip创建一个弹出窗口,显示控件的附加信息UserControl将UserControl类用作基类,可以为创建定制控件提供一种简单方式。但是,基类UserControl不支持模板WindowWindow类可以创建窗口和对话框。使用这个类,会获得一个带有最小化/最大化/关闭按钮和系统菜单的框架。在显示对话框时,可以使用方法ShowDialog(),方法Show()会打开一个窗口NavigationWindow类NavigationWindow派生自Window类,支持内容导航只有Frame控件包含在下面XAML代码的Window中。Source属性设置为,所以Frame控件导航到这个网站上,如图31-9所示。图 31-931.3.3 有标题的内容控件带标题的内容控件派生自HeaderContentControl基类。HeaderContentControl类又派生自基类ContentControl。 HeaderContentControl类的Header属性定义了标题的内容,HeaderTemplate属性可以对标题进行完全的定制。派生自基类HeaderContentControl的控件如表31-6所示。表 31-6HeaderContentControl说 明Expander使用Expander控件,可以创建一个带对话框的高级模式,它在默认情况下不显示所有的信息,只有用户展开它,才会显示更多的信息。在未展开模式下,只显示标题信息,在展开模式下显示内容GroupBoxGroupBox控件提供了边框和标题来组合控件TabItemTabItem控件是TabControl类中的项。TabItem的Header属性定义了标题的内容,这些内容用TabControl的标签显示Expander控件的简单用法如下面的例子所示。Expander控件的属性Header设置为Click for more。这个文本用于显示扩展。这个控件的内容只有在控件展开时才显示。图31-10中的示例程序包含折叠的Expander控件,图31-11中的示例程序展开了Expander控件。Short informationMore information here! 图 31-10 图 31-11提示:如果在展开Expander控件时,要修改该控件的标题文本,可以创建一个触发器,触发器详见本章后面的内容。31.3.4 项控件类ItemsControl包含一列可以用Items属性访问的数据项。派生自ItemsControl的类如表31-7所示。表 31-7ItemsControl说 明MenuContextMenu类Menu和ContextMenu派生自抽象基类MenuBase。把MenuItem元素放在数据项列表和相关的命令中,就可以给用户提供菜单StatusBarStatusBar控件通常显示在应用程序的底部,为用户提供状态信息。可以把StatusBarItem元素放在StatusBar列表中TreeView要分层显示数据项,可以使用TreeView控件ListBoxComboBoxTabControlListBox、ComboBox和TabControl都有相同的抽象基类Selector。这个基类可以从列表中选择数据项。ListBox显示列表中的数据项,ComboBox有一个附带的Button控件,只有点击按钮,才会显示数据项。在TabControl中,内容可以排列为表格31.3.5 带标题的项控件HeaderItemsControl是包含数据项和标题的控件的基类。类HeaderItemsControl派生自ItemsControl.派生自HeaderItemsControl的类如表31-8所示。表 31-8HeaderedItemsControl说 明MenuItem菜单类Menu和ContextMenu包含MenuItem类型的数据项。菜单项可以连接到命令上,因为MenuItem类实现了接口ICommandSourceTreeViewItem

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论