WPF学习之二:XAML学习
一、 什么是XAML?
什么是XAML呢?XAML是扩展应用程序标记语言(Extensible Application Markup Language),它是微软基于XML开发的一种声明式的用于创建UI的语言。XAML一般都是定义.xaml后缀格式的文件中。
二、 XAML中的元素
XML中的每个通过尖括号括起来的标记都称之为元素,XAML是基于XML产生的,因此对于这些标记,在XAML中也称之为元素。但是XAML中的元素种类有很多,下面将分类阐述。下面先给出一段代码,然后针对这段代码讲述各种元素。
<Grid>
<Grid.Children>
<Button Height="23" HorizontalAlignment="Left" Margin="25,51,0,0" Name="button1" VerticalAlignment="Top" Width="75">
<Button.Background>
<SolidColorBrush Color="Blue"></SolidColorBrush>
</Button.Background>
<Button.Foreground>
<SolidColorBrush Color="Red"></SolidColorBrush>
</Button.Foreground>
<Button.Content>
Click
</Button.Content>
</Button>
</Grid.Children>
</Grid>
1、对象元素
看上面的代码例子,那几个是对象元素呢?<Grid>和<Button>都是对象元素。在XAML中定义好了一些规则,XAML中的一些元素对应了CLR中的类型(类或结构)。比如<Grid>元素就对应了System.Windows.Controls.Grid类型,当你通过XAML标记定义了<Grid></Grid>元素对的时候,就相当于在后台代码中写一个实例化Grid的代码(Grid grid = new Grid();),这样就能在程序运行时,实例化对象。
对象元素的实例都是通过调用对象元素对应的CLR类型的默认构造函数进行创建的,因此类或结构如果需要作为对象元素,那么必须要有一个公开的默认构造函数。
2、属性(Property)元素
属性元素用于设置对象元素的属性(Property)。设置对象元素的属性不是可以通过设置属性(Attribute)值吗?那为什么还需要属性(Property)元素呢?这是因为简单的属性(Attribute)设置并不能满足这个对象元素的属性(Property)。但是对于同时支持属性(Attribute)语法和属性(Property)元素语法的属性,我们可以选择使用其中任何一种。
属性元素的语法为:<类型名称.属性>内容</类型名称.属性>。其中的内容就是作为属性值的某个类型的实例。
在上面的代码例子中:<Button.Background>、<Button.Foreground>等都是属性元素,其中包括的<SolidColorBrush Color="Blue"></SolidColorBrush>就是一个类实例。<Grid.Children>它也是属性元素,但这个属性元素等到将集合对象元素的时候再来详细讲述。
3、集合对象元素
集合对象元素指的是这个元素是一个对象元素,并且它对应的CLR类型是一个集合类型。这种类型的对象元素可以被省略。当你在标记代码中使用了集合类型的属性元素时,XAML处理器会自动创建相应的集合类型实例。根据MSDN说法,在XAML中这种特意省略集合对象元素的这种语法被称为”隐式集合语法”。
“隐式集合语法”适用于实现Ilist或Idictionary的类型,或者适用于数组。
在上面给出的代码中,在<Grid.Children>下面一层应该还存在一个<UIElementCollection>,但是它可以省略。此处不存在这个集合对象元素的另外一个原因是,它不能存在,因为这个类型不存在公开的默认构造函数。
三、 XAML中的属性
1、 属性(Attribute)语法
CLR类型中的属性(Property)在XAML标记语言中通常表示为属性(Attribute)。因此,通过设置对象元素的属性(Attribute)成为设置设置属性(Property)值最为直接的方法。
<Button Height="23" HorizontalAlignment="Left" Margin="25,51,0,0" Name="button1" VerticalAlignment="Top" Width="75">
如上面的代码中,设置了Height(高度)、HorizontalAligment(水平对齐)等等属性。
2、 属性(Property)元素语法
这个语法功能在上面的元素板块已经讲述,此处便不做阐述了。
3、 集合属性
这个属性在上面集合对象元素处也已经讲述,此处也不做阐述了。
4、 内容属性
内容属性是XAML提供的一个语言功能,它可以将CLR类型中的任何一个属性作为该类型实例的内容属性。设置内容属性的方法是在类上设置ContentPropertyAttribute。在标记中,XAML内容属性可以省略。同时,在标记中指定的任何子元素都将成为内容属性的值。
如上面代码<Grid.Children>,Children是Child从Panel中继承获得的,Panel将Children设置为其内容属性。因此该属性可以省略。
同时,必须注意,XAML内容属性的值必须是连续的,即它必须全部在该对象元素的其它属性元素之前或之后指定。
5、 附加属性(Property)
XAML提供了一种语言功能,它允许你在任何元素上指定某些属性,但是该属性可以不在当前指定的元素上。
按照MSDN说法,附加属性(Property)通常通过属性(Attribute)语法来设置。其语法格式为所有者类型.属性。
看下面的代码:
<DockPanel>
<Button DockPanel.Dock="Left" Height="23" Name="button1" Width="75">Button</Button>
</DockPanel>
上面的代码中Button将被放置在DockPanel的左边。通过这种附加属性就可以把子元素中设置其在父元素中的位置。
6、 依赖属性(Dependency Property)
依赖属性是XAML提供的一种很好的功能,它提供了一种方法,通过这种方法使我们可以通过其它输入值来计算目标属性值。依赖属性比较复杂,内容较多,下次再来详述。
四、 XAML中的类型转换(TypeConverter)
类型转化其实不是在XAML中刚出现的,在以前的版本中就已经有了,那以前用于干什么呢?最常用的属性窗口。属性窗口的的属性可不一定都是字符串,有许多复杂的类型,但是它都可以把它显示成字符串的形式,为什么?就是利用了类型转换,在字符串和不同类型之间进行转换。
其实现在的XAML属性(Attribute)也是如此,并非所有的属性值都是字符串,但是通过类型转换却可以把它转换成字符串,方便显示。具体如何使用,以后详述。
五、标记扩展(MarkupExtensible)
为什么要提供标记扩展功能呢?因为XAML需要一些标准功能或者默认行为无法满足的功能,比如属性赋值,它可能并不是直接赋一个字符串,而是要对已定义的对象的一个引用,由此便诞生了标记扩展。
标记扩展的语法是使用”{}”。
1、 特定于WPF的标记扩展
下面简单列举WPF中的重要标记扩展。
StaticResource:通过引用已定义资源的值来为XAML属性提供值。
DynamicResource:通过将资源的引用推迟到运行时来为XAML属性提供值。动态资源引用强制来每次访问此类资源时都进行重新访问。
Binding:按引用于元素的数据上下文来为属性提供数据绑定值。
RelativeSource:在运行时,为了可以在元素树中定位若干可能关系的Binding提供源信息。
TemplateBinding:提供数据模板绑定。
2、 XAML定义的标记扩展
x:Type:为所提供的类型提供Type对象。
x:Static:为属性值提供已定义的静态值。该静态值必须在引用之前定义。
x:Null:将null指定为XAML属性的值。
x:Array:为XAML中常规数组的创建提供支持。
六、XAML命名空间
1、系统命名空间映射
在每个通过VS进行创建的window或者page中,都存在以下两个命名空间。
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
第一个指的是WPF命名空间,它包括了大部分的WPF类型,并将其作为默认命名空间。
第二个指的是XAML命名空间,它指的是XAML可扩展标记语言的命名空间。
XAML是一个语言规范,或者语言定义。而WPF则是基于这种语言的一个实现。
2、映射自己的命名空间
其实,我们自已也可以把我们定义的类的命名空间映射到XAML中。如下面所示:
xmlns:local="clr-namespace:WpfApplication1;assembly=WpfApplication1"
如果你映射的命名空间就在当前程序集内,则assembly可以省略。
3、 将CLR命名空间映射为XAML命名空间
上面说的系统命名空间其实它也有CLR命名空间,只是它通过了一种方式把它进行了转换。它的方法就是使用XmlnsDefinitionAttribute。通过多次指定这个属性,可以将多个CLR命名空间映射为XAML命名空间。
我们可以通过使用Reflector工具来查看PresentationFramework.dll。用蓝色框框圈起来的就是相应的映射关系。