一、概述
定义XAML语法术语是XAML语言规范中进行定义或引用。XAML是基于XML的语言,遵循或扩展XML结构规则。XAML是基于描述XML语言或XML文档对象模型时常用的术语。
XAML是一种标记语言。CLR是可实现运行时语言。XAML不是CRL运行一部分。仅是使用于WPF的XAML时实例化运行的一种表达形式。
二、对象元素语法
对象元素语法是 XAML 标记语法,通过声明 XML 元素来实例化 CLR 类或结构。 此语法类似于其他标记语言(如 HTML)的元素语法。 对象元素语法以左尖括号 (<) 开头,后面紧跟进行实例化的类或结构的类型名称。 零个或多个空格可以跟在类型名称后面,零个或多个属性也可以在对象元素上声明,使用一个或多个空格分隔每个属性名称=“值”对。对象元素必须满足一下条件之一:
▪元素和标记必须以正斜杠 (/) 结尾,后面紧跟右尖括号 (>)。
▪开始标记必须以右尖括号 (>) 结尾。 其他对象元素、属性元素或内部文本可以跟在开始标记后面。 此处可能包含的确切内容通常受元素的对象模型约束。 对象元素的等效结束标记也必须存在,与其他开始和结束标记对进行正确的嵌套和平衡。
实例一:
<TextBox Text="TextBox" Width="120"/>
实例二:
<TextBox Text="TextBox" Width="120"></TextBox>
三、特性语法(属性)
特性语法是 XAML 标记语法,它通过对现有对象元素声明特性来设置属性的值。 特性名称必须与支持相关对象元素的类的属性的 CLR 成员名称匹配。 特性名称后跟赋值运算符 (=)。 特性值必须是括在引号中的字符串。
若要通过特性语法进行设置,属性必须是公共属性,并且必须可写。 后备类型系统中属性的值必须是值类型,或者必须是在访问相关后备类型时可由 XAML 处理器实例化或引用的引用类型。
对于 WPF XAML 事件,作为特性名称引用的事件必须是公共的,并且具有公共委托。
四、特性值的处理
左和右引号中包含的字符串值由 XAML 处理器进行处理。 对于属性,默认处理行为由基础 CLR 属性的类型确定。
特性值会按此处理顺序,使用以下内容之一进行填充:
1.如果XAML处理器遇到大括号或派生自MarkupExtension的对象元素,则首先计算引用的标记扩展,而不是将值作为字符串进行处理,标记扩展返回的对象会用作值。 在许多情况下,标记扩展返回的对象会是对现有对象的引用,或者是将计算延迟到运行时的表达式,不是新实例化的对象。
2.如果使用特性化TypeConverter声明属性,或者使用特性化TypeConverter声明该属性的值类型,则特性的字符串值会作为转换输入提交到类型转换器,转换器会返回新的对象实例。
3.如果没有TypeConverter,则尝试直接转换为属性类型。此最终在 XAML 语言基元类型之间对分析器本机值进行直接转换,或者检查枚举中命名常量的名称(分析器随后会访问匹配值)。
五、枚举特性值
XAML 中的枚举由 XAML 分析器以内部方式进行处理,枚举的成员应通过指定枚举命名常量之一的字符串名称来指定。对于非标志枚举值,本机行为是处理特性值的字符串并将它解析为枚举值之一。无需如同在代码中一样,以“枚举.值”格式指定枚举。 而是仅指定值,枚举通过所设置的属性类型进行推断。 如果以“枚举.值”形式指定特性,则不会正确进行解析。
对于按标志枚举,行为基于 Enum.Parse方法。 可以通过用逗号分隔每个值,为按标志枚举指定多个值。 但是,不能合并不按标志的枚举值。
六、属性和事件成员名称引用
指定属性时,可以引用以针对包含对象元素实例化的 CLR 类型的成员形式而存在的任何属性或事件。或者可以引用独立于包含对象元素的附加属性或附件事件。
使用 typeName.event 部分限定名称对可通过默认命名空间访问的任何对象中的任何事件进行命名;此语法支持为路由事件附加处理程序,其中处理程序旨在处理从子元素路由的事件,但父元素在其成员表中也不包含该事件。 此语法类似于附加事件语法,但此处的事件不是真正的附加事件。 而是使用限定名称引用事件。
七、属性元素语法
属性元素语法是一种与元素的基本 XML 语法规则有一些差异的语法。 在 XML 中,特性的值是事实上的字符串,唯一可能的变化是所使用的字符串编码格式。 在 XAML 中,可以分配其他对象元素作为属性的值。 属性元素语法在默认情况下会启用此功能。 属性不是在元素标记中指定为特性,而是采用 elementTypeName.propertyName 形式,使用开始元素标记进行指定,在其中指定属性的值,然后结束属性元素。具体而言,语法以左尖括号 (<) 开头,后面紧跟属性元素语法包含在其中的类或结构的类型名称。 紧接着是单个点 (.),然后是属性的名称,再然后是右尖括号 (>)。 与特性语法一样,该属性必须存在于指定类型的已声明公共成员中。
属性元素语法实例:
<Button> <Button.ContextMenu> <ContextMenu> <MenuItem Header="1">First item</MenuItem> <MenuItem Header="2">Second item</MenuItem> </ContextMenu> </Button.ContextMenu> Right-click me! </Button>
八、集合语法
XAML 规范要求 XAML 处理器实现标识值类型为集合的属性。 .NET 中的常规 XAML 处理器实现基于托管代码和 CLR,它通过下列方法之一标识集合类型:
▪类型实现IList
▪类型实现IDictionary
▪类型派生自Array
如果属性的类型是集合,则推断的集合类型不需要在标记中指定为对象元素。 相反,旨在成为集合中的项的元素被指定为属性元素的一个或多个子元素。
<Style x:Key="SpecialButton" TargetType="{x:Type Button}"> <Style.Triggers> <Trigger Property="Button.IsMouseOver" Value="true"> <Setter Property = "Background" Value="Red"/> </Trigger> <Trigger Property="Button.IsPressed" Value="true"> <Setter Property = "Foreground" Value="Green"/> </Trigger> </Style.Triggers> </Style>
九、XAML 内容属性
XAML 内容语法是一种仅在指定 ContentPropertyAttribute 作为类声明一部分的类上启用的语法。 ContentPropertyAttribute会引用作为该类型元素(包括派生类)的内容属性的属性名称。 由 XAML 处理器进行处理时,在对象元素的开始标记与结束标记之间找到的任何子元素或内部文本都会分配给该对象的 XAML 内容属性值。 允许为内容属性指定显式属性元素,但此用法通常不会出现在 .NET 参考的 XAML 语法部分中。 显式/详细技术偶尔对使标记清晰或是在标记样式方面有价值,但内容属性的意图通常是简化标记,以便可以直接嵌套直观上以父子形式相关的元素。 按照严格的 XAML 语言定义,元素上其他属性的属性元素标记不会分配为“内容”;它们以前按 XAML 分析器的处理顺序进行处理,不被视为“内容”。
▪XAML 内容属性值必须是连续的
AML 内容属性的值必须完全在该对象元素的其他任何属性元素之前或之后指定。 无论 XAML 内容属性的值是指定为字符串还是一个或多个对象,情况都是如此。 例如,以下标记不会进行分析:
<Button Margin="67,45,202,245"> <Button.Background>Blue</Button.Background> <Button.FontSize>Bold</Button.FontSize> <Button.Foreground>#FFFFF5F5</Button.Foreground> <Button.Content>这是一个有背景的按钮</Button.Content> </Button>
十、内容属性和集合语法组合
若要接受多个对象元素作为内容,内容属性的类型必须明确为集合类型。 与集合类型的属性元素语法类似,XAML 处理器必须标识属于集合类型的类型。 如果元素具有 XAML 内容属性,并且 XAML 内容属性的类型是集合,则隐式集合类型不需要在标记中指定为对象元素,并且 XAML 内容属性不需要指定为属性元素。 因此,标记中的明显内容模型现在可以将多个子元素分配为内容。
<Window x:Class="_010_WPF_Demo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:_010_WPF_Demo" mc:Ignorable="d" Title="MainWindow" Height="450" Width="900"> <Grid > <StackPanel Width="100" Height="200"> <Button>Button 1</Button> <Button>Button 2</Button> <Button>Button 3</Button> </StackPanel> </Grid> </Window>
十一、总结
XAML语法规范大致有以上几种常用的方式,在实际应用中会根据不同的场景,选择恰当的方式组合完成应用程序的开发。