XAML学习文档

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Xaml概述(wpf)
发送反馈
本主题介绍XAML 语言的功能,并演示如何使用XAML 编写Windows Presentation Foundation (WPF) 应用程序。

本主题专门介绍WPF 实现的XAML。

XAML 本身是一个比WPF 大的语言概念。

本主题包括下列各节。

∙什么是XAML?
∙XAML 语法概述
∙XAML 中的大小写和空白
∙标记扩展
∙类型转换器
∙XAML 根元素和XAML 命名空间
∙XAML 中的自定义前缀和自定义类型
∙事件和XAML 代码隐藏
∙XAML 命名元素
∙附加属性和附加事件
∙基类型和XAML
∙XAML 安全性
∙从代码中加载XAML
∙接下来的内容
∙相关主题
什么是XAML?
XAML 是一种声明性标记语言。

如同应用于.NET Framework 编程模型一样,XAML 简化了为.NET Framework 应用程序创建UI 的过程。

您可以在声明性XAML 标记中创建可见的UI 元素,然后使用代码隐藏文件(通过分部类定义与标记相连接)将UI 定义与运行时逻辑相分离。

XAML 直接以程序集中定义的一组特定后备类型表示对象的实例化。

这与大多数其他标记语言不同,后者通常是与后备类型系统没有此类直接关系的解释语言。

XAML 实现了一个工作流,通过此工作流,各方可以采用不同的工具来处理应用程序的UI 和逻辑。

以文本表示时,XAML 文件是通常具有.xaml扩展名的XML 文件。

可通过任何XML 编码对文件进行编码,但通常编码为UTF-8。

下面的示例演示如何创建作为UI 一部分的按钮。

此示例的目的仅在于供您初步了解XAML 是如何表示常用UI 编程形式的(它不是一个完整的示例)。

XAML
打印
<StackPanel>
<Button Content="Click Me"/>
</StackPanel>
XAML 语法概述
下面的章节介绍XAML 语法的基本形式,并提供一个简短的标记示例。

这些章节并不提供每个语法形式的完整信息,例如这
些语法如何在后备类型系统中表示。

有关本主题中介绍的每种语法形式在XAML 语法中的详情的更多信息,请参见XAML 语法详述。

如果您以前熟悉XML 语言,则下面几节中的很多材料对您而言都是基础知识。

这是XAML 的其中一个基本设计原则的结果。

XAML 语言定义它自己的概念,但这些概念在XML 语言和标记形式内发挥作用。

XAML 对象元素
对象元素通常声明类型的实例。

该类型在为以XAML 为语言的技术提供后备类型的程序集中定义。

对象元素语法始终以左尖括号(<) 开头,后跟要创建实例的类型的名称。

(该名称可能包含前缀,前缀的概念会在后面解释。

)在此之后,您可以选择声明该对象元素的特性。

要完成对象元素标记,请以右尖括号(>) 结尾。

您也可以使用不含任何内容的自结束形式,方法是用一个正斜杠后接一个右尖括号(/>) 来完成标记。

例如,请再次查看前面演示的标记代码段:
XAML
打印
<StackPanel>
<Button Content="Click Me"/>
</StackPanel>
此示例指定了两个对象元素:<StackPanel>(含有内容,后面有一个结束标记)和<Button .../>(自结束形式,包含几个特性)。

对象元素StackPanel和Button各映射到一个类名,这些类由WPF 定义并且是WPF 程序集的一部分。

指定对象元素标记时会创建一条XAML 处理指令来创建一个新实例。

每个实例都是在分析和加载XAML 时通过调用基础类型的
默认构造函数来创建的。

特性语法(属性)
对象的属性通常可表示为对象元素的特性。

特性语法命名在特性语法中设置的属性,后跟赋值运算符(=)。

特性的值始终以包含在引号中的字符串的形式进行指定。

特性语法是最简单有效的属性设置语法,并且对于曾使用过标记语言的开发人员而言在使用中是最直观的语法。

例如,以下标
记将创建一个具有红色文本和蓝色背景的按钮,还将创建指定为Content的显示文本。

XAML
打印
<Button Background="Blue"Foreground="Red"Content="This is a button"/>
属性元素语法
对于对象元素的某些属性,特性语法是不可能实现的,因为无法在特性语法的引号和字符串限制内充分地表达提供属性值所必
需的对象或信息。

对于这些情况,可以使用另一个语法,即属性元素语法。

属性元素开始标记的语法为<类型名称.属性名称>。

通常,该标记的内容是类型的一个对象元素,属性会将该元素作为其值。

指定内容之后,必须用一个结束标记结束属性元素。

结束标记的语法为</类型名称.属性名称>。

如果可以使用特性语法,那么使用特性语法通常更为方便,且能够实现更为精简的标记,但这通常只是一个风格的问题,而不
属于技术限制。

下面的示例演示了在前面的特性语法示例中设置的相同属性,但这次对Button的所有属性使用了属性元素语法。

XAML
打印
<Button>
<Button.Background>
<SolidColorBrush Color="Blue"/>
</Button.Background>
<Button.Foreground>
<SolidColorBrush Color="Red"/>
</Button.Foreground>
<Button.Content>
This is a button
</Button.Content>
</Button>
集合语法
XAML 语言包含一些优化,可以生成可读性更好的标记。

其中的一项优化是:如果某个特定属性采用集合类型,则您在标记中声明为该属性的值内的子元素的项将成为集合的一部分。

在这种情况下,子对象元素的集合是设置为集合属性的值。

下面的示例演示为GradientStops属性设置值的集合语法:
XAML
打印
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<!-- no explicit new GradientStopCollection, parser knows how to find or create -->
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
XAML 内容属性
XAML 指定了一个语言功能,通过该功能,一个类可以指定它的一个且仅一个属性为XAML 内容属性。

该对象元素的子元素用于设置该内容属性的值。

换言之,仅对内容属性而言,您可以在XAML 标记中设置该属性时省略属性元素,并在标记中生
成更直观的父级/子级形式。

例如,Border指定内容属性Child。

系统处理下面两个Border元素的方式相同。

第一个元素利用了内容属性语法而省略
了Border.Child属性元素。

第二个元素显式标明Border.Child。

XAML
打印
<Border>
<TextBox Width="300"/>
</Border>
<!--explicit equivalent-->
<Border>
<Border.Child>
<TextBox Width="300"/>
</Border.Child>
</Border>
作为XAML 语言的规则,XAML 内容属性的值必须完全在该对象元素的其他任何属性元素之前或之后指定。

例如,下面的标记无法进行编译:
<Button.Background>Blue</Button.Background>
blue button</Button>
有关XAML 内容属性的此项限制的更多信息,请参见XAML 语法详述的“XAML 内容属性”一节。

文本内容
有少量XAML 元素可直接将文本作为其内容来处理。

若要实现此功能,必须满足以下条件之一:
∙类必须声明一个内容属性,并且该内容属性必须是可赋值给字符串的类型(该类型可以是Object)。

例如,任何ContentControl都将Content用作其内容属性,并且其类型为Object,这样就支持实际的ContentControl(例
如,Button)上的如下用法:<Button>Hello</Button>。

∙类型必须声明一个类型转换器,该类型转换器将文本内容用作其初始化文本。

例如,<Brush>Blue</Brush>。

这种情况实际上并不常见。

∙类型必须为已知的XAML 语言基元。

内容属性和集合语法组合
请看以下示例:
XAML
打印
<StackPanel>
<Button>First Button</Button>
<Button>Second Button</Button>
</StackPanel>
此例中,每个Button都是StackPanel的一个子元素。

这是一个简单直观的标记,其中出于两个不同的原因省略了两个标记。

∙省略的StackPanel.Children 属性元素:StackPanel从Panel派生。

Panel将Panel .Children 定义为其XAML 内容属性。

省略的UIElementCollection 对象元素:Panel .Children 属性采用类型UIElementCollection,该类型实现IList。

根据处理集合(例如IList)的XAML 规则,集合的元素标记可以省略。

(在这种情况下,UIElementCollection实际无
法实例化,因为它没有公开默认构造函数,这就是UIElementCollection对象元素以注释形式出现的原因。


XAML
打印
<StackPanel>
<StackPanel.Children>
<!--<UIElementCollection>-->
<Button>First Button</Button>
<Button>Second Button</Button>
<!--</UIElementCollection>-->
</StackPanel.Children>
</StackPanel>
特性语法(事件)
特性语法还可用于事件成员,而不仅限于属性成员。

在这种情况下,特性的名称为事件的名称。

在XAML 事件的WPF 实现中,特性的值是实现该事件的委托的处理程序的名称。

例如,以下标记将Click事件的一个处理程序指定给在标记中创建的Button:XAML
打印
<Page
xmlns="/winfx/2006/xaml/prese ntation"
xmlns:x="/winfx/2006/xaml"
x:Class="ExampleNamespace.ExamplePage">
<Button Click="Button_Click" >Click Me!</Button>
</Page>
除此特性语法示例外,还有更多关于WPF 中的事件和XAML 的内容。

例如,您可能希望了解此处引用的ClickHandler表示什么,以及它是如何定义的。

这将在本主题中后面的事件和XAML 代码隐藏一节中解释。

XAML 中的大小写和空白
XAML 通常区分大小写。

出于解析后备类型的目的,WPF XAML 按照CLR 区分大小写的相同规则区分大小写。

按名称与程
序集中的基础类型进行比较或者与类型的成员进行比较时,对象元素、属性元素和特性名称均必须使用区分大小写的形式指定。

XAML 语言关键字和基元也区分大小写。

值并不总是区分大小写。

值是否区分大小写将取决于与采用该值的属性关联的类型转换器行为,或取决于属性值类型。

例如,采用Boolean类型的属性可以采用true或True作为等效值,但只是因为将字符串转换为Boolean的本机WPF XAML 分析器类型转换已经允许将这些值作为等效值。

WPF XAML 处理器和序列化程序将忽略或删除所有无意义的空白,并规范化任何有意义的空白。

这与XAML 规范的默认空白行为建议一致。

通常,只有当您在XAML 内容属性中指定字符串时,此行为的重要性才会体现出来。

简言之,XAML 将空格、换行符和制表符转化为空格,如果它们出现在一个连续字符串的任一端,则保留一个空格。

有关XAML 空白处理的完整说明
不属于本主题的讨论范围。

有关详细信息,请参见XAML 中的空白处理。

标记扩展
标记扩展是一个XAML 语言概念。

当用于提供特性语法的值时,大括号({和})表示标记扩展用法。

此用法指示XAML 处理系统不要像通常那样将特性值视为一个文本字符串或者可转换为字符串的值。

WPF 应用程序编程中最常用的标记扩展是Binding(用于数据绑定表达式)以及资源引用StaticResource和DynamicResource。

通过使用标记扩展,即使属性通常不支持特性语法,也可以使用特性语法为属性提供值。

标记扩展经常使用中间表达式类型实现一些功能,例如,推迟值或引用仅在运行时才存在的其他对象。

例如,下面的标记使用特性语法设置Style属性的值。

Style属性采用了Style类的一个实例,该实例默认情况下未能用特性语法字符串实例化。

但在本例中,特性引用了特定的标记扩展StaticResource。

当处理该标记扩展时,它返回对以前在资源字典中作为键控资源进行实例化的某个样式的引用。

XAML
打印
<Page.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Gold"/>
<Style TargetType="Border" x:Key="PageBackground">
<Setter Property="Background" Value="Blue"/>
</Style>
...
</Page.Resources>
<StackPanel>
<Border Style="{StaticResource PageBackground}">
...
</Border>
</StackPanel>
有关特定在WPF 中实现的所有XAML 标记扩展的参考列表,请参见WPF XAML 扩展。

有关由System.Xaml 定义并且可更广泛用于.NET XAML 实现的标记扩展的参考列表,请参见XAML 命名空间(x:) 语言功能。

有关标记扩展概念的更多信息,请参见标记扩展和WPF XAML。

类型转换器
在特性语法一节中,曾提到特性值必须能够使用字符串进行设置。

对字符串如何转换为其他对象类型或基元值的基本本机处理取决于String类型本身,以及对某些类型(如DateTime或Uri)的本机处理。

但是很多WPF 类型或这些类型的成员扩展了基本字符串特性处理行为,因此可以指定更复杂的对象类型的实例作为字符串和特性。

Thickness结构是一个类型示例,该类型拥有可使用XAML 的类型转换。

Thickness指示嵌套矩形中的度量并用作一些属性
(如Margin)的值。

通过对Thickness设置类型转换器,所有使用Thickness的属性都可以更容易地在XAML 中指定,因为它们可指定为特性。

下面的示例使用类型转换和特性语法来为Margin提供值:
XAML
打印
<Button Margin="10,20,10,30" Content="Click me"/>
上面的特性语法示例与下面更为详细的语法示例等效,但在下面的示例中,Margin改为通过包含Thickness对象元素的属性元素语法进行设置。

而且设置Thickness的四个关键属性作为新实例的特性:
XAML
打印
<Button Content="Click me">
<Button.Margin>
<Thickness Left="10" Top="20" Right="10" Bottom="30"/> </Button.Margin>
</Button>
说明
有关如何支持类型转换及其在特性语法上的应用的更多信息,请参见TypeConverters 和XAML。

XAML 根元素和XAML 命名空间
一个XAML 文件只能有一个根元素,这样才能同时成为格式正确的XML 文件和有效的XAML 文件。

对于典型的WPF 方案,将使用在WPF 应用程序模型中具有重要意义的根元素(例如,为页使用Window或Page,为外部字典使
用ResourceDictionary或为应用程序定义使用Application)。

下面的示例演示WPF 页的典型XAML 文件的根元素,此根元素为Page。

XAML
打印
<Page
xmlns="/winfx/2006/xaml/prese ntation"
xmlns:x="/winfx/2006/xaml" ...
</Page>
根元素还包含特性xmlns和xmlns:x。

这些特性向XAML 处理器指明哪些XAML 命名空间包含标记将要作为元素引用的后备类型的类型定义。

xmlns特性明确指示默认的XAML 命名空间。

在默认的XAML 命名空间中,可以不使用前缀指定标记中的对象元素。

对于大多数WPF 应用程序方案以及SDK 的WPF 部分中给出的几乎所有示例,默认的XAML 命名空间均映射到为WPF 命名空间/winfx/2006/xaml/presentation。

xmlns:x特性指示另外一个XAML 命名空间,该命名空间映射XAML 语言命名空间/winfx/2006/xaml。

使用xmlns定义用法范围和名称范围映射的做法符合XML 1.0 规范。

XAML 名称范围与XML 名称范围的不同仅在于:XAML 名称范围还包含有关进行类型解析和分析XAML 时名称范围的元素如何受类型支持的信息。

请注意,只有在每个XAML 文件的根元素上,xmlns特性才是绝对必需的。

xmlns定义将适用于根元素的所有子代元素(此行为也符合xmlns的XML 1.0 规范。

)同时允许根以下的其他元素上具有xmlns特性,这些特性将适用于定义元素的任何子代元素。

但是,频繁定义或重新定义XAML 命名空间可能会导致XAML 标记样式难以阅读。

其XAML 处理器的WPF 实现包括可识别WPF 核心程序集的基础结构。

已知WPF 核心程序集包含支持WPF 到默认XAML 命名空间的映射的类型。

这是通过属于项目生成文件以及WPF 生成和项目系统一部分的配置来实现的。

因此,为了引用来自WPF 程序集的XAML 元素,只需将默认XAML 命名空间声明为默认xmlns。

x: 前缀
在上面的根元素示例中,前缀x:用于映射XAML 命名空间/winfx/2006/xaml,该命名空间是支持XAML 语言构造的专用XAML 命名空间。

在这整个SDK 的项目模板、示例以及文档中,此x:前缀用于映射该XAML 命名空间。

XAML 语言的XAML 命名空间包含多个将在XAML 中频繁用到的编程构造。

下面列出了将用到的最常见的x:前缀编程构造:
∙x:Key:为ResourceDictionary(或其他框架中的类似字典概念)中的每个资源设置唯一的键。

在典型的WPF 应用程序标记中的所有x:用法中,x:Key将可能占到90%。

∙x:Class:向为XAML 页提供代码隐藏的类指定CLR 命名空间和类名。

必须具有这样一个类才能支持每个WPF 编程模型的代码隐藏,而正是因此,即使没有资源,也几乎总是能看到映射的x:。

∙x:Name:处理对象元素后,为运行时代码中存在的实例指定运行时对象名称。

通常,您将为x:Name经常使用WPF 定义的等效属性。

此类属性特定映射到CLR 后备属性,因此更便于进行应用程序编程,在应用程序编程中,您经
常使用运行时代码从初始化的XAML 中查找命名元素。

最常见的此类属性是FrameworkElement .Name 。

在特定类型中不支持等效的WPF 框架级Name属性时,仍然可以使用x:Name。

某些动画方案中会发生这种情况。

∙x:Static:启用一个返回静态值的引用,该静态值只能是一个XAML 兼容属性。

∙x:Type:根据类型名称构造一个Type引用。

它用于指定采用Type(例如Style .TargetType )的特性,但属性经常具有本机的字符串到Type的转换功能,因此使用x:Type标记扩展用法是可选的。

x:前缀/XAML 命名空间中还有其他一些不太常见的编程构造。

有关详细信息,请参见XAML 命名空间(x:) 语言功能。

XAML 中的自定义前缀和自定义类型
对于您自己的自定义程序集或PresentationCore、PresentationFramework 和WindowsBase 的WPF 核心以外的程序集,可以将
该程序集指定为自定义xmlns映射的一部分。

只要该类型能够正确地实现以支持您所尝试的XAML 用法,就可以在XAML 中
引用该程序集中的类型。

下面是一个说明自定义前缀如何在XAML 标记中工作的基本示例。

前缀custom在根元素标记中定义,并映射为随应用程序
一同打包并可用于该应用程序的一个特定程序集。

此程序集包含NumericUpDown类型,实现该类型的目的是在支持常规XAML 用法之外,还可以使用允许在WPF XAML 内容模型的此特定点执行插入的类继承。

通过使用该前缀,此NumericUpDown控件的一个实例声明为对象元素,以便XAML 分析器可找到包含该类型的XAML 命名空间,从而找到包
含该类型定义的后备程序集的位置。

xmlns="/winfx/2006/xaml/prese ntation"
xmlns:x="/winfx/2006/xaml"
xmlns:custom="clr-namespace:NumericUpDownCustomControl;as sembly=CustomLibrary"
>
<StackPanel Name="LayoutRoot">
<custom:NumericUpDown Name="numericCtrl1" Width="100" Height="60"/>
...</StackPanel>
</Page>
有关XAML 中自定义类型的更多信息,请参见XAML 及WPF 的自定义类。

有关XML 命名空间与程序集中后备代码的命名空间如何相关的更多信息,请参见WPF XAML 的XAML 命名空间和命名空
间映射。

事件和XAML 代码隐藏
大多数WPF 应用程序既包括XAML 标记,也包括代码隐藏。

在一个项目中,XAML 编写为.xaml文件,而CLR 语言(如Microsoft Visual Basic .NET 或C#)用于编写代码隐藏文件。

在WPF 编程和应用程序模型中对XAML 文件进行标记编译时,XAML 文件的XAML 代码隐藏文件的位置是通过如下方式来标识的:以XAML 的根元素的x:Class特性形式指定一个命名
空间和类。

在目前已介绍的示例中,您已看到几个按钮,但还没有一个按钮具有任何关联的逻辑行为。

为对象元素添加行为的主要应用程
序级机制是使用元素类的现有事件,并为在运行时引发该事件时调用的该事件编写特定的处理程序。

事件名称以及要使用的处
理程序的名称在标记中指定,而实现处理程序的代码在代码隐藏中定义。

XAML
打印
<Page
xmlns="/winfx/2006/xaml/prese ntation"
xmlns:x="/winfx/2006/xaml"
x:Class="ExampleNamespace.ExamplePage">
<Button Click="Button_Click" >Click Me!</Button>
</Page>
VB
C#
C++
F#
JScript
打印
namespace ExampleNamespace
{
public partial class ExamplePage
{
void Button_Click(object sender, RoutedEventArgs e)
{
Button b = e.Source as Button;
b.Foreground = Brushes.Red;
}
}
}
请注意,代码隐藏文件使用CLR 命名空间ExampleNamespace并将ExamplePage声明为该命名空间内的一个分部类。

这相当于在标记根中提供的ExampleNamespace. ExamplePage的x:Class特性值。

WPF 标记编译器将通过从根元素类型派生一个类,为编译的任何XAML 文件创建一个分部类。

当您提供也会定义同一分部类的代码隐藏时,将在与编译的应用程序相同的命名空间和类中组合生成的代码。

有关WPF 中代码隐藏编程要求的更多信息,请参见WPF 中的代码隐藏和XAML中的“代码隐藏、事件处理程序和分部类要求”一节。

如果您不想创建一个单独的代码隐藏文件,还可以将代码内联到XAML 文件中。

但是,内联代码是一种缺少多样性的方法,有很多的限制。

有关详细信息,请参见WPF 中的代码隐藏和XAML。

路由事件
路由事件是一个特殊的事件功能,该功能是WPF 的基础。

路由事件使一个元素可以处理另一个元素引发的事件,前提是这些元素通过树关系连接在一起。

使用XAML 特性指定事件处理时,可以对任何元素(包括未在类成员表中列出路由事件的元素)侦听和处理该路由事件。

这是通过以所属类名限定事件名特性来实现的。

例如,在当前所讨论的StackPanel /Button示例中,父StackPanel可以通过在StackPanel对象元素上指定特性Button.Click,并使用处理程序名作为特性值,为子元素按钮的Click事件注册一个处理程序。

有关路由事件如何工作的更多信息,请参见路由事件概述。

XAML 命名元素
默认情况下,通过处理XAML 对象元素在对象图中创建的对象实例没有唯一标识符或对象引用。

相反,如果在代码中调用构造函数,则几乎总是使用构造函数结果为构造的实例设置一个变量,以便以后在代码中引用该实例。

为了对通过标记定义创建的对象提供标准化访问,XAML 定义了x:Name 特性。

您可以在任何对象元素上设置x:Name特性的值。

在代码隐藏中,您选择的标识符等效于引用所构造的实例的实例变量。

在任何方面,命名元素都像它们是对象实例一样工作(此名称引用该实例),并且代码隐藏可以引用该命名元素来处理应用程序内的运行时交互。

实例和变量之间的这种连接是由WPF XAML 标记编译器实现的,并且更具体涉及到功能和模式,例如本主题中将不详细讨论的InitializeComponent。

WPF 框架级XAML 元素继承Name属性,该属性等效于XAML 定义的x:Name特性。

其他某些类也为x:Name(通常也定义为Name属性)提供属性级等效项。

一般而言,如果您在所选元素/类型的成员表中找不到Name属性,则可以改
用x:Name。

x:Name值将通过特定子系统或通过诸如FindName等实用工具方法,为可在运行时使用的XAML 元素提供标识符。

下面的示例在StackPanel元素上设置Name。

然后,该StackPanel中的Button上的处理程序通过由Name设置的实例引
用buttonContainer来引用StackPanel。

XAML
打印
<StackPanel Name="buttonContainer">
...
<Button Click="RemoveThis">Click to remove this
button</Button>
</StackPanel>
VB
C#
C++
F#
JScript
打印
void RemoveThis(object sender, RoutedEventArgs e)
{
FrameworkElement fe = e.Source as FrameworkElement;
if (buttonContainer.Children.Contains(fe))
{
buttonContainer.Children.Remove(fe);
}
}
就像变量一样,实例的XAML 名称受范围概念的控制,因此可以在可预测的某个范围内强制名称唯一。

定义页面的主标记表
示一个唯一的XAML 名称范围,而该XAML 名称范围的边界就是该页面的根元素。

但是,其他标记源(如样式或样式中的
模板)可以在运行时与页面交互,这种标记源常常具有自己的XAML 名称范围,这些名称范围不一定与页面的XAML 名称
范围相关联。

有关x:Name和XAML 名称范围的更多信息,请参见Name、x:Name 特性或WPF XAML 名称范围。

附加属性和附加事件
XAML 指定了一个语言功能,该功能允许对任何元素指定某些属性或事件,而不管要设置属性或事件的元素的类型定义中是否存在该属性或事件。

该功能的属性版本称为附加属性,事件版本称为附加事件。

从概念上讲,可以将附加属性和附加事件视为
可以在任何XAML 元素/对象实例上设置的全局成员。

但是,元素/类或更大的基础结构必须支持附加值的后备属性存储。

通常通过特性语法来使用XAML 中的附加属性。

在特性语法中,您可以采用“所有者类型. 属性名”的形式指定附加属性。

表面上,这与属性元素用法类似,但在这种情况下,您指定的“所有者类型”始终是一种与从中要设置附加属性的对象元素不同
的类型。

“所有者类型”这种类型提供XAML 处理器为获取或设置附加属性值所需要的访问器方法。

使用附加属性的最常见方案是使子元素能够向其父元素报告属性值。

下面的示例演示了DockPanel .Dock 附加属性。

DockPanel类为DockPanel .Dock 定义访问器,因此拥有附加属性。

DockPanel类还包括一个逻辑,该逻辑迭代其子元素并具体检查每个元素是否具有DockPanel .Dock 设置值。

如果找到一个值,将在布局过程中使用该值定位子元素。

使用DockPanel .Dock 附加属性和这种定位功能事实上是DockPanel类的激动人心的一面。

XAML
打印
<DockPanel>
<Button DockPanel.Dock="Left"Width="100"Height="20">I am on the left</Button>
<Button DockPanel.Dock="Right" Width="100" Height="20">I am on the right</Button>
</DockPanel>
在WPF 中,大部分或所有附加属性还作为依赖项属性来实现。

有关详细信息,请参见附加属性概述。

附加事件使用类似的“所有者类型. 事件名”特性语法形式。

就像非附加事件一样,XAML 中的附加事件的特性值指定对元素处理事件时调用的处理程序方法的名称。

在WPF XAML 中使用附加事件并不常见。

有关更多信息,请参见附加事件概述。

基类型和XAML
基础WPF XAML 及其XAML 命名空间是类型的一个集合,这些类型对应于CLR 对象以及XAML 的标记元素。

但是,并
不是所有的类都能映射到元素。

抽象类(如ButtonBase)和某些非抽象基类在CLR 对象模型中用于继承。

基类(包括抽象类)对于XAML 开发仍然很重要,因为每个具体的XAML 元素都从其层次结构中的某个基类继承成员。

通常,这些成员包括可
以设置为元素特性的属性或者可以处理的事件。

FrameworkElement是WPF 在WPF 框架级的具体UI 基类。

设计UI 时,您将使用各种形状、面板、修饰器或控件类,它们全部从FrameworkElement派生而来。

有一个相关的基类FrameworkContentElement,它使用可在FrameworkElement中特意镜像API 的API,支持适合流布局表示形式的面向文档的元素。

元素级的特性和CLR 对象模型的组合提供了一组通用的属性,这些属性可以在大多数具体的XAML 元素上设置,而不管具体的XAML 元素类型及
其基础类型是什么。

相关文档
最新文档