标签:
→ XAML文档中的每个元素都映射为.NET类的一个实例,元素的名称也完全对应于类名。如元素<Button>指示WPF创建Button对象。
→ 与所有XML文档一样,可在一个元素中嵌套另一个元素,XAML让每个类灵活地决定如何处理嵌套。嵌套通常是一种表示“包含”的方法——如果在一个Grid元素中发现一个Button元素,那么用户界面可能包括 一个在其内部包含一个Button元素的Grid元素。
→ 可通过attribute设置每个类的property。在某些attribute不足以达到效果的情况下,需要通过特殊的语法使用嵌套的标签(tag)。
新建空白项目自动生成代码如下(例1):
1 <Window x:Class="WPFDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Grid> 6 </Grid> 7 </Window>
这份代码仅含两个元素——顶级的Window元素以及一个Grid元素,Window元素代表整个窗口,在Grid元素中可以放置所有控件。尽管可使用任何顶级元素,但WPF应用程序只使用以下元素作为顶级元素:
→ Window元素
→ Page元素(该元素和Window元素类似,但用于可导航的应用程序)
→ Application元素(该元素定义应用程序资源和启动设置)
与所有XML文档中一样,XAML文档中只能有一个顶级元素。在上面的示例中,只要使用</Window>标签关闭了Window元素,文档就结束了,在后面不能再有任何内容了。
显然,只提供类名是不够的,XAML解析器还需要知道类位于哪个.NET名称空间。
xmlns特性是XML中的一个特殊特性,它专门用来声明名称空间。例1中2、3两行标记声明了两个名称空间,第2行是WPF核心名称空间,它包含了所有WPF类,包括用来构建用户界面的控件。这个名称空间的声明没有使用名称空间前缀,它成为整个文档的默认名称空间,除非另行指明,每个元素自动位于这个名称空间。第3行是XAML名称空间,包含各种XAML实用特性,这些特性可影响文档的解释方式。这个名称空间被映射为前缀x,这意味着可通过在元素名称之前放置名称空间前缀x来使用该名称空间,如<x:ElementName>.
通过XAML可以构造用户界面。为了使应用程序具有一定的功能,需要用于连接包含应用程序代码的事件处理程序方法。XAML通过使用形如例1中第1行的代码的Class特性实现了这个问题。Class特性告诉XAML解析器用指定的名称生成一个新类,该类继承自由XML元素名称的类。换句话说,该例创建了一个名为MainWindow的新类,该类继承自Window基类。
namespace WPFDemo { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } } }
本质上,InitializeComponent()方法的所有工作就是调用System.Windows.Application类的LoadComponentt()方法。LoadComponent()方法从程序集中提取BAML,并用它来构建用户界面。当解析BAML时,它会创建每个控件对象,设置其属性,并关联所有事件处理程序。
XAML特性中的值总是纯文本字符串,但对象的属性可以是任何.NET类型。为了关联字符串值和非字符串属性,XAML解析器需要进行转换。由类型转化器执行转换,类型转换器是从.NET 1.0起就已经引入的.NET基础结构的一个基本组成部分。XAML解析器通过以下两个步骤来查找类型转换器:
1.检查属性声明,查找TypeConverter特性,如果提供了TypeConverter特性,该特性将指定哪个类可执行转换。例如,当使用Foreground这样的属性时,.NET将检查Foreground属性的声明。
2.如果在属性声明中没有TypeConverter特性,XAML解析器将检查对应数据类型的类声明。例如,Foreground属性使用一个Brush对象,由于Brush类使用TypeConverter(typeof(BrushConverter))特性声明进行了修饰i,因此Brush类及其子类使用BrushConverter类型转换器。
如果在类层次上设置一个类型转换器,该转换器将应用到所有使用这个类的属性上。另一方面,如果希望为某个特定属性微调类型转换方式,那么可以在属性声明中改用TypeConverter特性。如果属性声明或类声明都没有与其关联的类型转化器,XAML解析器会生成错误。
虽然类型转换器便于使用,但它们不能解决所有的实际问题。例如,有些属性时完备的对象,这些对象具有自己的一组属性。尽管创建供类型转换器使用的字符串表示形式是可行的,但使用这种方法时语法可能十分复杂且易出错。
不过,XAML提供了另一种选择:属性元素语法。使用属性元素语法,可添加名称形如Parent.PropertyName的子元素。例如,Grid控件有一个Background属性,该属性允许提供用于绘制控件背景区域的画刷,如果希望使用更复杂的画刷,就需要添加名为Grid.Background的子标签。其中.(Dot)发挥了重要作用,它把属性和其他类型的嵌套内容区分开来。一旦识别出想要配置的复杂属性,该如何配置呢?可以在嵌套元素内部添加其他标签来实例化特定的类。
对于大多数属性而言,XAML属性语法可以工作的很好。但有些情况下,不可能硬编码属性值。例如,可能希望将属性值设置为一个已经存在的对象,或者可能希望通过一个属性绑定到另一个空间来动态地设置属性值。这两种情况都需要使用标记扩展。
标记扩展可用于嵌套标签或XML特性中。当用在特性中时, 它们总是被花括号抱起来。例如,下面的标记演示了如何使用标记扩展,它允许引用另一个类中的镜头属性:
<Button ... Foreground="{x:Static SystemColors.ActiveCaptionBrush)">
标记扩展使用{ 标记扩展类 参数}语法。在上面的示例中,标记扩展是StaticExtension类,根据约定,在引用扩展类时可以省略最后一个单词Extension。所有标记扩展都由继承自System.Windows.Markup.MarkupExtension基类的类实现。MarkupExtension提供了一个简单的ProvideValue()方法类获取所期望的数值。也就是说,当XAML解析器遇到上述语句时,它将创建StaticExtension类的一个以字符串SystemColors.ActiveCaptionBrush作为构造函数参数的实例,然后调用ProvideValue()方法获取SystemColors.ActiveCaptionBrush静态属性返回的对象,最后使用检索的对象设置cmdAnswer按钮的Foreground属性。XAML最终结果与下面代码相同:
cmdAnswer.Foreground=SystemColors.ActiveCaptionBrush;
因为标记扩展映射为类,所有也可用作嵌套属性,可以像下面这样为Button.Foreground属性使用StaticExtension标记扩展:
<Button ...> <Button.Foreground> <x:Static Member="SystemColors.ActiveCaptionBrush"></x:Static> </Button.Foreground> </Button>
标签:
原文地址:http://www.cnblogs.com/johnvwan/p/4526772.html