零起点学习WPF之《WPF揭秘》读书笔记(2)
2.7 对象元素的 子元素
XAML文件就像是所有的XML文件一样,都必须有一个单独的根对象元素。因此不必感到惊讶,对象元素是可以支持子对象元素的【不只是支持属性元素、考虑XAML时,他们并不是子元素】
一种类型的对象元素可以有三种类型的子元素:
(1)内容属性值,(2)集合项,(3)或者是一个可以通过类型转化器转化到父元素的值。
2.7.1内容元素
大多数WPF类指定了一个属性,该属性可以被设置为XAML元素的任何内容,这个属性就叫做内容属性,内容属性是一个让XAML呈现变得更加轻便简洁的一个捷径。
例如:
用内容元素去表示就可以写成如下格式:
<Button xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation">
OK
<Button>
还有一种更加厉害的呢:
<Button xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Button.Content>
<Rectangle Height = "40" width = "40" Fill ="Black"/>
</Button.Content>
</Button>
用内容元素去表示可以表示为:
<Button xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Rectangle Height ="40" Width = "40" Fill= "Black"/>
</Button>
是不是有点惊讶啊? 嘿嘿…
注意:并不是把内容元素叫做Content,像System.Windows.Controls命名空间的的类,如Combox,ListBox,TabControl,这样的类中 使用Item属性作为内容元素。
2.7.2集合项
XAML允许将项添加到支持索引的两种类型的集合中:List 和Dictionary.
******************************List***************************
List实现了System.Conllections.IList接口。如:System.Collection.ArrayList 和 许多WPF定义的集合类都是List.
<ListBox xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<ListBox.Items>
<ListBoxItem Content = "Item 1"/>
<ListBoxItem Content = "Item2"/>
</ListBox.Items>
</ListBox>
由于Items 是内容属性,所以如上的代码可以简化为:
<ListBox xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<ListBoxItem Content ="Item 1"/>
<ListBoxItem Content = "Item 1"/>
</ListBox>
********************************Dictionary******************************
System.Windows.ResoucreDictionary 是WPF中的一个常用的集合类型,以后详细讲解。
它实现了System.Collection.IDictionary接口,因此能够在支持过程式的代码中实现、添加、移除、和枚举键值对,这与创建一个典型的散列表是一样的。
下面的XAML实现添加两个Color到一个ResourceDictionary
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
>
<Color x:key = "1" A="255" R="255"G="255" B="255"/>
<Color x:key ="2" A="0" R="0"G="0"B="0"/>
</ResourceDictionary>
注意带有 x;key 的XAML中总是被指定的值总是作为字符串去处理的,除非使用标记扩展,但不会去尝试使用类型转换。
2.7.3更多类型转换
普通文本经常被用作对象元素的自元素。例如:
<SolidColorBrush>White</SolidColorBrush>
这与下面的代码是等价的,<SoldColorBrushColor = "White">
尽管Color没有被指定为内容元素,在本例中,第一个XAML之所以能够正常执行,是因为有类型转换器的存在,它会把字符串'White'或者是'#FFFFFF'转换成SolidColorBrush对象。
虽然类型转换器在实现XAML可读性方面起了重大作用,但它不足的是,它们让XAML变得更加魔幻、从而更加难以理解XAML是如果映射到.NET对象的实例。
使用目前的知识,你还无法声明一个抽象的XAML类元素,因为我们没有办法去实例化它。
由于System.Windows.Media.Brush是SolidColorBrush 和 GradientBrush 及一些具体笔刷的抽象基类,顾可以如下表示之前的代码:<Brush>White<Bursh>
这是因为Bursh 类型转换器仍然可以把它理解为一个SolidColorBrush。这可能是一个比较不寻常的特性,但是在XAML中支持原始类型表达能力很重要。
对象元素的XAML元素的处理规则
在当前的情况下有三种类型的对象元素的子元素,为了避免混淆,我们定义如下的规则:
(1)如果该类型实现了IList接口,则为每一个子元素都调用一次Ilist.Add方法。
(2)否则,如果该类型实现类IDictionary接口,则为每一个元素调用Idictionary.Add方法,在该值的键和元素中使用x:key特性值。
(3)否则,如果父元素支持内容属性(由System.Windows.Markup.ContentPropertyAttribute表示),而且子元素的类型与该内容属性是兼容的,就把子元素作为它的值。
(4)否则,如果子对象是普通文本,且有类型转化器将子对象转换成父类型(没有在父元素上设置属性),则把子元素作为作为类型转化器的输入,把输出作为父对象的实例。