WPF基础教程XAMl.docx
- 文档编号:6074239
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:14
- 大小:311.40KB
WPF基础教程XAMl.docx
《WPF基础教程XAMl.docx》由会员分享,可在线阅读,更多相关《WPF基础教程XAMl.docx(14页珍藏版)》请在冰豆网上搜索。
WPF基础教程XAMl
本主题介绍可扩展应用程序标记语言(XAML)语言的功能,并演示如何使用XAML编写WindowsPresentationFoundation(WPF)应用程序。
本主题专门介绍了WindowsPresentationFoundation(WPF)实现的XAML.XAML本身是比WindowsPresentationFoundation(WPF)更广泛的一个语言概念。
具有流控制支持的声明性语言XAML简化了为.NETFramework编程模型创建UI的过程。
您可以在声明性XAML标记中创建可见的UI元素,然后使用代码隐藏文件(通过分部类定义与标记相连接)将UI定义与运行时逻辑相分离。
在XAML中混合代码和标记的功能很重要,因为XML本身是声明性的,不会为流控制真正建议一个模型。
基于XML的声明性语言非常直观,可以为用户(尤其是具有Web设计和技术背景的人员)创建从原型到生产的各种界面。
与其他大多数标记语言不同,XAML直接呈现托管对象的实例化。
这种常规设计原则简化了使用XAML创建的对象的代码和调试访问。
XAML文件是指通常使用.xaml扩展名的XML文件。
下面的XAML示例演示了小标记在创建作为UI一部分的按钮时的必要性。
创建的按钮通过主题样式获得默认的可视化表示形式,通过其类设计获得默认的行为。
XAML对象元素
XAML有一组规则,这些规则将对象元素映射为类或结构,将属性(Attribute)映射为属性(Property)或事件,并将XML命名空间映射为CLR命名空间。
XAML元素映射为被引用程序集中定义的Microsoft.NET类型,而属性(Attribute)则映射为这些类型的成员。
上面的示例指定了两个对象元素:
<STACKPANEL>(具有一个结束标记)和<BUTTON>同样具有多个属性;下一节将介绍属性)。
字符串StackPanel和Button都将映射为某个类的名称,该类由WPF定义并且是WPF程序集的一部分。
在指定对象元素标记时,可以为XAML处理创建一条指令,以便在加载XAML页时创建指定类的一个新实例。
每个实例都是通过调用基础类或结构的默认构造函数并对结果进行存储而创建的。
为了可用作XAML中的对象元素,该类或结构必须公开一个公共的默认(无参数)构造函数。
设置属性
XAML中的属性是通过使用各种可能的语法在对象元素上设置属性来设置的。
根据所设置的属性的特征,给定属性可使用的语法会有所不同。
通过设置属性值,可以为对象元素添加功能或特征。
对象元素的基础对象实例的初始状态基于默认的构造函数行为。
通常,您的应用程序将使用其他一些实例,而不是任何给定对象的完全默认的实例。
属性语法
在XAML中,属性(Property)常常可以表示为属性(Attribute)。
属性(Attribute)语法是最简单的属性(Property)设置语法,并将成为过去使用标记语言的开发人员可以使用的最直观的语法。
例如,以下标记将创建一个具有红色文本和蓝色背景的按钮,还会创建指定为Content的显示文本。
属性元素语法
对于一个对象元素的某些属性(Property),属性(Attribute)语法是不可能实现的,因为提供属性(Property)值所需的对象或信息不能充分地表示为简单的字符串。
对于这些情况,可以使用另一个语法,即属性元素语法。
属性元素语法用标记的内容设置包含元素的引用的属性。
一般而言,内容就是作为属性值的类型的某个对象(值设置实例通常被指定为另一个对象元素)。
属性元素本身的语法为<类型名称.属性>。
指定内容之后,必须用一个结束标记结束属性元素,就像其他任何元素(语法为)一样。
对于同时支持属性(Attribute)和属性(Property)元素语法的属性(Property),尽管这两种语法的细微之处(如空白处理)略有不同,但它们的结果通常是一样的。
如果可以使用属性(Attribute)语法,那么使用属性(Attribute)语法通常更为方便,且能够实现更为精简的标记,但这只是一个风格的问题,而不属于技术限制。
下面的示例演示了在前面的属性(Attribute)语法示例中设置的相同属性(Property),但这次对Button的所有属性(Property)使用了属性(Property)元素语法。
XAML的属性(Property)元素语法表示了与标记的基本XML解释之间的巨大背离。
对于XML,<类型名称.属性>代表了另一个元素,该元素仅表示一个子元素,而与TypeName父级之间没有必然的隐含关系。
在XAML中,<类型名称.Property>直接表示Property是类型名称的属性(由属性元素内容设置),而绝不会是一个名称相似(碰巧名称中有一个点)但却截然不同的元素。
属性和类继承
作为WPF元素的XAML属性(Attribute)而出现的属性(Property)通常从基类继承而来。
例如,在上一个示例中,如果您要查看类定义、反射结果或文档,Background属性并不是在Button类上直接声明的属性。
相反,Background是从基Control类继承而来。
WPFXAML元素的类继承行为是与标记的基本XML解释之间的另一个巨大背离。
使用类继承(尤其是中间基类为抽象类时)的另一个原因在于,通过XML编程常用的架构类型(如DTD或XSD格式)几乎不可能准确且完整地表示XAML元素及其允许属性集。
另外,XAML中的“X”表示“extensible”(可扩展),而可扩展性破坏了“什么是用于WPF的XAML”的任何给定表示形式的完整性。
引用值和标记扩展
标记扩展是一个XAML概念。
在属性语法中,花括号({和})表示标记扩展用法。
此用法指示XAML处理不要像通常那样将属性值视为一个字符串或者可直接转换为文本字符串的值。
当属性采用引用类型值时,这些属性常常需要属性元素语法(始终创建一个新实例)或通过标记扩展的对象引用。
标记扩展用法有可能会返回现有实例,因此可以更加多样化,或者产生较少的对象系统开销。
当使用标记扩展提供属性值时,应改为由相关标记扩展的后备类中的逻辑提供属性值。
WPF应用程序编程中最常用的标记扩展是Binding(用于数据绑定表达式)以及资源引用StaticResource和DynamicResource.通过使用标记扩展,即使属性(Property)不支持对直接对象实例化使用属性(Attribute)语法,也可以使用属性(Attribute)语法为属性(Property)提供引用值;或者使特定行为能够符合必须用属性(Property)类型值填充XAML属性(Property)这一常规行为要求。
例如,下面的示例使用属性(Attribute)语法设置Style属性(Property)的值。
Style属性(Property)采用了Style类的一个实例,这是默认情况下不能在属性(Attribute)语法字符串中指定的引用类型。
但在本例中,属性(Attribute)引用了特定的标记扩展StaticResource.当处理该标记扩展时,它返回对以前在资源字典中作为键控资源进行实例化的某个样式的引用。
资源只是WPF或XAML启用的一种标记扩展用法。
支持Typeconverter的属性值
在“属性语法”一节中,曾提到属性值必须能够使用字符串进行设置。
对字符串如何转换为其他对象类型或基元值的基本本机处理取决于String类型本身。
但是很多WPF类型或这些类型的成员扩展了基本字符串属性处理行为,因此更复杂的对象类型的实例可通过字符串指定为属性值。
在代码级别,此处理是通过指定处理字符串属性值的CLR类型转换器来完成的。
常用于指示矩形区域尺寸(如Margin)的Thickness结构类型是这样一个类型的示例:
它具有针对采用该类型的所有属性(Property)公开的一个特殊的、支持类型转换器的属性(Attribute)语法,以便于在XAML标记中使用。
下面的示例使用支持类型转换器的属性(Attribute)语法来为Margin提供值:
上面的属性(Attribute)语法示例与下面更为详细的语法示例等效,但在下面的示例中,Margin是通过包含Thickness对象元素的属性(Property)元素语法设置的,而且Thickness的四个关键属性(Property)设置为新实例的属性(Attribute):
是使用支持类型转换器的语法,还是使用更详细的等效语法,通常只是编码风格的选择问题,但支持转换器的语法有助于生成更简洁的标记。
(但是,有一些对象只能采用类型转换器将属性设置为该类型,因为类型对象本身并没有默认的构造函数。
例如,Cursor。
)
集合类型和XAML集合属性
XAML指定了一个语言功能,通过该功能,可以从标记中特意省略表示集合类型的对象元素。
当XAML处理 器处理采用了集合类型的属性时,将隐式创建相应集合类型的实例,即使标记中不存在该集合的对象元素也是如此。
在集合类型的SDK参考页中,特意省略集合对象元素的这种语法在XAML语法部分中有时候称为“隐式集合语法”。
隐式集合语法适用于实现IList或IDictionary的类型,或者适用于数组。
您已经在XAML资源示例中看到了未调用的集合对象元素的隐式集合语法的示例:
除了根元素外,页面上作为另一个元素的子元素而嵌套的每个对象元素实际上都是下列一种或两种情况下的元素:
父元素的隐式集合属性的一个成员,或者为父元素指定XAML内容属性值的元素(XAML内容属性将在下一节进行讨论)。
换言之,一个标记页上的父元素与子元素之间的关系实际上就是一个根对象,而根对象下面的每个对象元素要么是为父元素提供属性值的一个实例,要么是同样作为父元素的集合类型属性值的集合中的一项。
在资源示例的案例中,Resources属性采用ResourceDictionary类型的一个对象。
下面的示例在语法上与显式指定的ResourceDictionary的对象元素等效。
Resources集合是许多常见的WPF框架级元素上存在的集合属性的一个示例。
在XAML中设置此属性需要使用属性元素语法。
属性元素中的每个被包含的对象元素都成为集合(IDictionary实现)中的一个项。
虽然集合类型本身通常没有包含项的属性或索引器,但是该属性不能在标记中指定;它完全是隐含的。
对于ResourceDictionary,该属性是Item索引器。
XAML内容属性
XAML指定了一个语言功能,通过该功能,任何可以用作XAML对象元素的类都可以确切指定其属性之一作为该类实例的XAML内容属性。
当XAML处理器处理具有XAML内容属性的对象元素时,该对象元素的任何XML子元素都被当作包含在一个表示该内容属性的隐式属性元素标记中来处理。
在标记中,可以省略XAML内容属性的属性元素语法。
在标记中指定的任何子元素都将成为XAML内容属性的值。
您已经看过了未调用的XAML内容属性的示例:
本主题中的第一个示例。
这里,Button是StackPanel的子元素。
这是一个简单直观的标记,其中出于两个不同的原因省略了两个标记。
省略的StackPanel.Children属性元素:
StackPanel从Panel派生。
Panel将Panel……:
:
。
Children定义为其XAML内容属性。
Panel的所有派生类因而具有该XAML内容属性,而Panel……:
:
。
Children的属性元素可省略。
省略的UIElementCollection对象元素:
Panel……:
:
。
Children属性采用类型UIElementCollection,该类型实现IList.因此,根据为集合定义的XAML规则,可以省略UIElementCollection对象元素标记。
在这种情况下,UIElementCollection实际上不能实例化为一个对象元素。
您甚至无法显式声明该集合对象。
这是因为UIElementCollection不公开默认的构造函数。
其他几个WPF集合类型也不公开对象元素用法的构造函数,因为XAML集合语法处理仍然允许它们在XAML中隐式工作。
这就是UIElementCollection对象元素在示例中显示为已被注释的原因;如果未被注释,示例将不能编译。
内部文本和XAML内容属性
StackPanel/Button示例还有另一种变体。
请注意为Button指定的显示文本如何发生变化。
前面已在属性(Attribute)语法中指定了Content属性(Property);这次显示字符串是Button对象元素中的内部文本。
此语法可行,因为Content是Button基类ContentControl的XAML内容属性。
元素中的字符串根据Content属性的属性类型(即Object)进行计算。
Object不会尝试任何字符串类型转换,因此Content属性的值变成了文本字符串值。
或者,Button中的内容可以是任何单个Object。
Button等控件通常为类定义XAML内容属性,因此XAML内容属性可用于UI和显示文本,或用于控件合成,或同时用于此两者。
对于流程文档模型和本地化而言,在元素中放置字符串作为内容以生成与其他常见标记语言类似的标记的功能特别重要。
XAML内容属性值必须连续
XAML内容属性的值必须完全在该对象元素的其他任何属性元素之前或之后指定。
不管XAML内容属性的值指定为字符串还是指定为一个或多个对象都是如此。
例如,下面的标记无法进行编译:
这在本质上是非法的,因为如果此语法是通过使用内容属性的属性元素语法而变为显式的,则内容属性将设置两次:
一个类似的非法示例是,如果内容属性是一个集合,则子元素是与属性元素交错的:
内容模型
从语法上讲,可能支持将类用作XAML元素,但只有放置到整体内容模型或元素树中的所需位置时,该元素才能在应用程序或页面上正常运行。
例如,MenuItem通常只应作为MenuBase派生类(如Menu)的子级放置。
特定元素的内容模型在可用作XAML元素的控件和其他WPF类的类页面上的备注中进行说明。
对于具有更复杂内容模型的某些控件,内容模型作为单独的概念主题进行说明。
XAML中的大小写和空白
XAML区分大小写。
按名称与程序集中的基础类型进行比较或者与类型的成员进行比较时,必须使用正确的大小写指定所有对象元素、属性(Property)元素和属性(Attribute)名称。
属性的值并不总是区分大小写。
值是否区分大小写将取决于与采用该值的属性关联的类型转换器行为,或取决于属性值类型。
例如,采用Boolean类型的属性可以采用true或True作为等效值,但只是因为Boolean的默认字符串类型转换已经允许这些值作为等效值。
XAML处理器和序列化程序将忽略或删除所有无意义的空白,并规范化任何有意义的空白。
只有当您在XAML内容属性中指定字符串时,才会体现此行为的重要性。
简言之,XAML将空格、换行符和制表符转化为空格,如果它们出现在一个连续字符串的任一端,则保留一个空格。
有关XAML语法的更多信息
隐式集合语法和XAML内容属性都是允许省略某些推断标记的XAML语言功能。
这些功能的目的是在编写或检查标记时使页面上的元素的父子关系更明显。
如果您正在创建自定义类,并且正在考虑是否允许使用XAML,XAML语法术语主题也是一个很好的起点。
XAML根元素和xmlns
一个XAML文件只能有一个根元素,这样才能成为格式正确的XML文件和有效的XAML文件。
通常,应选择属于应用程序模型一部分的元素(例如,为页面选择Window或Page,为外部字典选择ResourceDictionary,或为应用程序定义根选择Application)。
下面的示例演示WPF页面的典型XAML文件的根元素,其中的根元素为Page。
根元素还包含属性xmlns和xmlns:
x。
这些属性向XAML处理器指明哪些命名空间包含标记将要引用的元素的元素定义。
xmlns属性专门指示默认的xmlns命名空间。
在默认的xmlns命名空间中,可以不使用前缀指定标记中的对象元素。
对于大多数WPF应用程序方案以及SDK的WPF部分中给出的几乎所有示例,默认的xmlns命名空间均映射为WPF命名空间属性指示另外一个xmlns命名空间,该命名空间映射XAML语言命名空间规范定义的必需语言组件带有x:
前缀。
使用xmlns定义用法范围和映射的这种做法符合XML1.0规范。
请注意,xmlns属性仅在每页的根元素上和应用程序定义上(如果在标记中提供了应用程序定义)才是严格必需的。
xmlns定义将应用于根的所有子元素。
(此行为仍然符合xmlns的XML1.0规范。
)xmlns属性还允许出现在根下面的其他元素上,并且将应用于定义元素的任何子元素。
但是,此用法并不典型,因为频繁定义或重新定义xmlns命名空间可能会导致XAML标记样式难以阅读。
由于存在属于项目生成文件一部分的配置,因此可以知道WPF程序集包含的某些类型支持WPF到默认xmlns的映射。
程序集还映射到目标文件中。
因此,为了引用来自WPF程序集的XAML元素,只需映射xmlns即可。
对于您自己的自定义程序集,或者除WPF之外的程序集,可以将该程序集指定为xmlns映射的一部分。
通常,可选择其他前缀,但是也可以选择其他xmlns作为默认值,然后将WPF映射到前缀。
x:
前缀
在前面的根元素示例中,前缀x:
用于映射XAMLxmlnsSDK的项目模板、示例以及文档中,此x:
前缀将用于映射XAMLxmlns.x:
前缀/XAMLxmlns包含多个将在XAML中频繁用到的编程构造。
下面列出了将用到的最常见x:
前缀/XAMLxmlns编程构造:
x:
Key:
为ResourceDictionary中的每个资源设置一个唯一的键。
在应用程序标记中看到的所有x:
用法中,x:
Key可能占到90%.x:
Class:
向为XAML页提供代码隐藏的类指定CLR命名空间和类名。
必须具有这样一个类才能支持代码隐藏,也正是由于这个原因,即使没有资源,您也几乎总是会看到映射的x:
。
x:
Name:
处理对象元素后,为运行时代码中存在的实例指定运行时对象名称。
在不支持等效的WPF框架级Name属性的情况下命名元素时,可以使用x:
Name.某些动画方案中会发生这种情况。
x:
Static:
启用一个获取静态值的值引用,该静态值只能是一个XAML可设置属性。
x:
Type:
根据类型名称构造一个Type引用。
它用于指定采用Type的属性(Attribute),如Style……:
:
。
TargetType,不过在许多情况下属性(Property)本身具有字符串到Type的转换功能,因此使用x:
Type是可选的。
x:
前缀/XAMLxmlns中还有其他一些不太常见的编程构造。
事件和XAML代码隐藏
大多数WPF应用程序都是既包括标记,又包括代码隐藏。
在一个项目中,XAML被编写为.xaml文件,而使用CLR语言(如MicrosoftVisualBasic.NET或C#)编写代码隐藏文件。
编译XAML文件时,每个XAML页的XAML代码隐藏文件的位置是通过指定一个命名空间和类作为XAML页的根元素的x:
Class属性来确定的。
在目前已介绍的示例中,您已看到几个按钮,但还没有一个按钮具有任何关联的逻辑行为。
为对象元素添加行为的主要应用程序级机制是使用元素类的现有事件,并为在运行时引发该事件时调用的该事件编写特定的处理程序。
事件名称以及要使用的处理程序的名称在标记中指定,而实现处理程序的代码在代码隐藏中定义。
请注意,代码隐藏文件使用命名空间MyNamespace并将MyPageCode声明为该命名空间内的一个分部类。
这相当于在标记根中提供的MyNamespace.MyPageCode的x:
Class属性值。
编译器将通过从根元素类型派生一个类,自动为编译的任何XAML页创建一个分部类。
当您提供也会定义同一分部类的代码隐藏时,将在与编译的应用程序相同的命名空间和类中组合生成的代码。
如果您不想创建单独的代码隐藏文件,还可以将代码内联到XAML文件中。
但是,内联代码是一种缺少多样性的方法,有很多的限制。
事件属性语法
当您在标记中通过事件指定行为时,通常使用属性语法来附加处理程序。
在其中指定事件属性的对象元素则变成侦听事件以及调用处理程序的实例。
您要处理的具体事件的名称是属性名。
属性值是您要定义的处理程序的方法名。
然后您必须在代码隐藏中提供处理程序实现,并使处理程序基于该事件的委托。
您使用编程语言(如MicrosoftVisualBasic.NET或C#)在代码隐藏中编写处理程序。
引发事件时,每个WPF事件都将报告事件数据。
事件处理程序可以访问这些事件数据。
在前面的示例中,处理程序通过事件数据获取所报告的事件源,然后在该事件源上设置属性。
路由事件
路由事件是一个特殊的事件功能,该功能是WPF特有的并且是它的基础。
路由事件允许一个元素处理另一个元素引发的事件,只要这些元素通过元素树关系连接起来。
当使用XAML属性指定事件处理时,可以在任何元素(包括未在类成员表中列出该特定事件的元素)上侦听和处理路由事件。
这是通过使用所属类名限定事件名属性来实现的。
例如,在当前所讨论的StackPanel/Button示例中,父StackPanel可以通过在StackPanel对象元素上指定属性Button.Click,并使用处理程序名作为属性值,为子元素按钮的
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- WPF 基础教程 XAMl