分享(C#高级编程第6版doc)第34章 Windows Presentatio.doc_第1页
分享(C#高级编程第6版doc)第34章 Windows Presentatio.doc_第2页
分享(C#高级编程第6版doc)第34章 Windows Presentatio.doc_第3页
分享(C#高级编程第6版doc)第34章 Windows Presentatio.doc_第4页
分享(C#高级编程第6版doc)第34章 Windows Presentatio.doc_第5页
已阅读5页,还剩52页未读 继续免费阅读

下载本文档

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

文档简介

第34章Windows Presentation FoundationWindows Presentation Foundation(WPF)是.NET Framework 3.0中的三个主要扩展之一。WPF是为智能客户应用程序创建UI的一个新库。Windows窗体控件基于Windows内置控件,利用了基于屏幕像素的Windows句柄。而WPF基于DirectX。应用程序不再使用Windows句柄,更便于重新设置UI的大小,并内置了音频和视频的支持。本章的主要论题如下:WPF概述用作基本绘图元素的图形利用转换功能实现缩放、旋转和倾斜填充元素的不同笔刷WPF控件及其特性如何用WPF面板定义布局WPF事件处理机制样式、模板和资源34.1 概述WPF的一个主要特性是设计人员和开发人员的工作很容易分开。设计人员的工作成果可以直接供开发人员使用。为此,必须理解XAML。本章的第一个主题是概述WPF,理解XAML的规则,讨论设计人员和开发人员如何合作。WPF由几个包含了上千个类的程序集组成。因此用户可以在这些类中浏览,查找需要的类,大致了解WPF中的类层次结构和命名空间。34.1.1 XAMLXML for Applications Markup Language(XAML)是一种XML语法,用于定义用户界面的层次结构。在下面的代码行中,声明了一个内容为Click Me!、名为button1的按钮。元素指定使用Button类:Click Me!提示:XAML元素总是有一个.NET类。在特性和子元素中,可以设置属性的值,定义事件的处理程序方法。为了测试简单的XAML代码,可以启动实用工具XAMLPad.exe(参见图34-1),在编辑字段中输入XAML代码。在XAMLPad中,可以在已准备好的和元素中编写元素。利用XAMLPad可以立即查看XAML结果。(点击查看大图)图 34-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;button1.Click +=(sender, e) = MessageBox.Show(Button clicked);Application app = new Application();app.Run(mainWindow);提示:Application类也可以用XAML定义。在Visual Studio WPF项目中,打开App.xaml文件,它包含Application类的属性和StartupUri。运行应用程序,会得到一个包含按钮的窗口,如图34-2所示。(点击查看大图)图 34-2可以看出,WPF的编程非常类似于Window窗体的编程,其区别是按钮有Content属性,而不是Text属性。但是,与通过代码创建UI窗体相比,XAML有一些非常好的优点。利用XAML,设计人员和开发人员可以更好地合作。设计人员可以用XAML代码设计一个漂亮的UI,开发人员在使用C#在后台代码中添加功能。使用XAML更便于将UI与功能分开。使用后台代码和XAML,可以在C#代码中直接与用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!标记扩展主要用于访问资源和数据绑定,本章后面将讨论这两个主题。34.1.2 设计人员和开发人员的合作开发人员常常不仅要实现Windows应用程序,还负责应用程序的设计。尤其是应用程序仅用于内部使用,就更是如此。如果雇用懂得UI设计技巧的人来设计UI,开发人员通常会得到设计人员的一个JPG文件,该文件描述了UI的外观。接着开发人员就要试图实现设计人员的规划。设计人员的一个简单修改,如给列表框和按钮指定不同的外观,就需要开发人员投入大量的精力设计定制的控件。因此,开发人员设计的UI与最初的设计大相径庭。WPF改变了这种情况。设计人员和开发人员可以使用相同的XAML代码。设计人员可以使用Expression Blend工具,开发人员则使用Visual Studio 2008,但他们可以用同一个项目文件工作。在这个合作过程中,设计人员使用与Visual Studio中相同的项目文件在Expression Blend中启动一个项目,接着,开发人员编写后台代码,同时设计人员改进UI。在开发人员改进功能的同时,设计人员还可以利用开发人员提供的功能,添加新的UI特性。当然,还可以用Visual Studio启动应用程序,以后再用Expression Blend改进UI。只是要小心,不要像处理Windows窗体那样设计UI,因为这没有充分利用WPF。图34-3显示了用WPF创建的Expression Blend。(点击查看大图)图 34-3提示:比较Expression Blend和Visual Studio扩展,Expression Blend的优秀特性有定义样式、创建动画、使用图形等。为了合作,Expression Blend可以使用开发人员编写的后台编码类,设计人员可以在WPF元素中指定与.NET类的数据绑定。设计人员还可以在Expression Blend中启动完整的应用程序,来测试它。因为Expression Blend使用与Visual Studio相同的MS-Build文件,所以能编译后台编码的C#代码,运行应用程序。34.1.3 类层次结构WPF包含上千个类,有很深的层次结构。为了帮助理解类之间的关系,图34-4在一个类图中列出了一些WPF类。表34-1描述了一些类及其功能。图 34-4 表 34-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窗体参见第31和32章。WPF的命名空间及其功能如表34-2所述。表 34-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文档的类34.2 形状形状是WPF的核心元素。利用形状,可以绘制矩形、线条、椭圆、路径、多边形和多义线等二维图形,这些图形用派生自抽象类Shape的类表示。图形在System.Windows. Shapes命名空间中定义。下面的XAML示例绘制了一个带腿的黄色笑脸,它用一个椭圆表示笑脸,两个椭圆表示眼睛,一个路径表示嘴,四个线条表示腿:图34-5显示了这些XAML代码的结果。无论是按钮还是线条、矩形等图形,所有这些WPF元素都可以通过编程来访问。把Path元素的Name属性设置为mouth,就可以用变量名mouth以编程方式访问这个元素:在Path元素的后台编码属性Data中,mouth设置为一个新的图形。为了设置路径,Path类支持PathGeometry和路径标记语法。字母M定义了路径的起点,字母Q指定了二次贝塞尔曲线的一个控制点和终点。运行应用程序,会看到如图34-6所示的窗口。public Window1()InitializeComponent();mouth.Data = Geometry.Parse(M 62,125 Q 95,122 102,128);(点击查看大图)图 34-5 (点击查看大图)图 34-6在本章的前面提到,按钮可以包含任何内容。对XAML代码做一点儿修改,将Button元素作为内容添加到窗口中,会使图形显示在按钮中,如图34-7所示。(点击查看大图)图 34-7 表34-3描述了System.Windows.Shapes命名空间中的图形。表 34-3Shape类说 明Line可以在坐标X1,Y1到X2,Y2之间绘制一条线Rectangle使用Rectangle类,可以指定Width和Height,绘制一个矩形Ellipse使用Ellipse类,可以绘制一个椭圆Path使用Path类可以绘制一系列直线和曲线。Data属性是Geometry类型。还可以使用派生自基类Geometry的类绘制图形,或使用路径标记语法来定义图形Polygon使用Polygon类可以绘制由线段连接而成的封闭图形。多边形由一系列赋予Points属性的Point对象定义PolyLine类似于Polygon类,使用PolyLine也可以绘制连接起来的线段,与多边形的区别是多义线不一定是封闭图形34.3 变换因为WPF基于DirectX,DirectX是基于矢量的,所以可以重置每个元素的大小。基于矢量的图形现在可以缩放、旋转和倾斜。即使没有手工计算位置,也可以进行单击测试(例如移动鼠标和单击鼠标)。给Canvas元素的LayoutTransform属性添加ScaleTransform元素,如下所示,把整个笑脸的内容在X和Y方向上放大2倍。旋转与缩放的执行方式相同。使用RotateTransform元素,可以定义旋转的角度:对于倾斜,可以使用SkewTransform元素。此时可以指定X和Y方向的倾斜角度:图34-8显示了这些变换的结果。这些图放在一个StackPanel中。从左到右,第一个图重置了大小,第二个图旋转了,第三个图倾斜了。为了更容易看出它们的区别,可以把Canvas元素的Background属性设置为不同的颜色。图 34-8 34.4 笔刷本节介绍如何使用WPF提供的笔刷绘制背景和前景。本节将参考图34-9,它显示了在Button元素的Background属性上使用各种笔刷的效果。图 34-9 34.4.1 SolidColorBrush图34-9中的第一个按钮使用了SolidColorBrush,顾名思义,这个笔刷使用纯色。完成的区域用同一种颜色绘制。把Background属性设置为定义纯色的字符串,就可以定义纯色。该字符串会转换为一个SolidColorBrush元素。Solid Color当然,设置Background子元素,把SolidColorBrush元素添加为它的子内容,也可以得到这个效果。应用程序中的第二个按钮给背景使用了纯色Yellow:YellowSolid Color34.4.2 LinearGradientBrush对于平滑的颜色变化,可以使用LinearGradientBrush,如第三个按钮所示。这个笔刷定义了StartPoint和EndPoint属性。使用这些属性可以为线性渐变指定两个坐标。默认的渐变方向是从0,0到1,1的对角线。定义其他值可以给渐变指定不同的方向。例如,StartPoint指定为0,0,EndPoint指定为0,1,就得到了一个垂直渐变。StartPoint不变,EndPoint指定为1,0,就得到了一个水平渐变。在这个笔刷中,可以用GradientStop元素定义指定偏移位置的颜色值。在各个偏移位置之间,颜色是平滑过渡的。Linear Gradient Brush34.4.3 RadialGradientBrush使用RadialGradientBrush可以以放射方式产生平滑的颜色改变。在图34-9中,第四个按钮使用了RadialGradientBrush。这个笔刷定义了从GradientOrigin点开始的颜色。Radial Gradient Brush34.4.4 DrawingBrushDrawingBrush可以定义用笔刷绘制的图形。用笔刷绘制的图形在GeometryDrawing元素中定义。Geometry属性中的GeometryGroup元素包含Geometry元素,例如EllipseGeometry、LineGeometry、RectangleGeometry和CombineGeometry。RedDrawing Brush34.4.5 ImageBrush要把图像加载到笔刷中,可以使用ImageBrush元素。在这个元素中,显示了ImageSource属性定义的图像。WhiteImage Brush34.4.6 VisualBrushVisualBrush可以在笔刷中使用其他WPF元素。下面给Visual属性添加一个WPF元素。图34-9中的第7个按钮包含一个矩形、一个椭圆和一个按钮。A ButtonVisual Brush在VisualBrush中,还可以创建反射等效果。这里显示的按钮包含一个StackPanel,它包含一个边框和一个矩形。边框包含一个StackPanel,该StackPanel又包含一个标签和一个矩形。但这不是重点。第二个矩形是用VisualBrush填充的。这个笔刷定义了一个不透明值和一个变换。Visual属性绑定到Border元素上。变换是通过设置VisualBrush的RelativeTransform属性来完成的。这个变换使用了相对坐标。把ScaleY设置为-1,完成了Y向的反射。TranslateTransform在Y向上移动变换,使反射效果位于原对象的下面。图34-9中的第8个按钮(VisualBrush2)显示了其效果。提示:这里使用的数据绑定和Binding元素详见下一章。YellowVisual Brush 2只要把Visual属性设置为MediaElement,就可以使用VisualBrush显示视频。对于MediaControl,Source属性应设置为WMV文件。在图34-9中,第9个按钮显示了3个女人,它就是显示视频的一个例子。但是在纸质媒介中,很难显示视频。读者可以自己试一试-如果使用Windows Vista的Ultimate版本,就可以在硬盘上找到这个视频。否则,可以选择另一个视频文件。34.5 控件可以给WPF使用上百个控件。为了更好地理解它们,我们把控件分为如下类别:简单控件内容控件有标题的内容控件项控件有标题的项控件34.5.1 简单控件简单控件是没有Content属性的控件。例如,Button类可以包含任意图形、任意元素,这对于简单控件而言没有问题。表34-4列出了简单控件及其功能。表 34-4简 单 控 件说 明PasswordBoxPasswordBox控件用于输入密码。这个控件有用于输入密码的特殊属性,例如PasswordChar定义了在用户输入密码时显示的字符,Password可以访问输入的密码。PasswordChanged事件在修改密码时调用ScrollBarScrollBar控件包含一个Thumb,用户可以在Thumb中选择一个值。如果文档在屏幕中放不下,就可以使用滚动条。一些控件包含滚动条,如果内容过多,就显示滚动条ProgressBar使用ProgressBar控件,可以指示某个时间较长的操作的进度Slider使用Slider控件,用户可以移动Thumb,选择一个范围的值。ScrollBar、ProgressBar和Slider派生自同一个基类RangeBaseTextboxTextbox控件用于显示简单的无格式文本RichTextboxRichTextbox控件通过FlowDocument类支持带格式的文本。RichTextBox和TextBox派生自同一个基类TextBoxBase提示:尽管简单控件没有Con

温馨提示

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

评论

0/150

提交评论