说明:本系列基本上是《WPF揭秘》的读书笔记。在结构安排与文章内容上参照《WPF揭秘》的编排,对内容进行了总结并加入一些个人理解。 |
类型转换器
上篇文章中我们已经与类型转换器有了第一次接触,我们看到通过类型转换器将字符串转换为整形。.NET类型转换器(TypeConverter)用于扩展XAML的表达能力,其可以在运行时计算类型为字符串的Attribute的值,生成一个适当的类型的对象。通俗的说就是完成字符串类型与属性本来的类型之间的转换。我们通过例子阐释一下这个抽象的概念:
对比一下如下两段分别用C#与XAML语言描述的功能等价的代码(省略去前一篇中介绍的命名空间的引用):
C#
Button b = new Button(); b.Content = "OK"; b.Background = System.Windows.Media.Brushes.White; |
XAML
<Button Content="OK" Background="White" /> |
仔细观察这段代码,或者你看过前文,你就会发现,在XAML中设置Background属性使用了一个字符串,而在C#中设置这个Background属性时使用了Brushes的属性White(类型为System.Windows.Media.SolidColorBrush)。XAML解析器处理这个问题时,会寻找一个知道如何将一个字符串转换为一种预期的数据类型的类型转换器。
WPF/Silverlight提供了许多类型的类型转换器,如针对Brush(BrushConverter), Color(ColorConverter), FontWeight, Point等的转换器。你也可以为自定义的类型编写类型转换器。类型转化器通常不区分字符串的大小写。
XAML中设置给XML Attribute的字符串知道怎样选择适当的类型转换器来处理字符串。其原理在于,这些属性如上文提到的BackgroundProperty,还有WidthProperty、HeightProperty等都被标记为TypeConverterAttribute来表明这个属性需要类型转换器来处理。另外像是有些属性Stroke,Fill等,虽然没有标记为TypeConverterAttribute,但是他们的基类Brush标有此Attribute以表明需要使用BrushConverter来转换。
例如:
<Rectangle Width="100" Height="20" Stroke="Black" Fill="VerticalGradient Black Red"/> |
Stroke属性交由BrushConverter处理后将得到相关的SolidColorBrush。而Fill属性将会由BrushConverter建立一个渐变画刷,其C#等价代码如下:
Rectangle r = new Rectangle(); r.Fill = new LinearGradientBrush(Colors.Black, Colors.Red, 90.0); |
如果设置非标准类型则需要提供自定义的转化器,如前文所述。
属性元素
在传统的设置对象属性的方式中,如对象属性是一种简单类型的对象,像将一个Button的Height设置为30,在XAML中可以使用如下XML Attribute的方式表示:
<Button Height="30"></Button> |
但是当一个属性可以并需要接受一个复杂的类型的对象,如需要设置Button的Content属性为一个Rectangle对象时。我们就无法继续使用XML Attribute这种较为简洁的写法,在XAML中我们可以使用名为属性元素的语法来完成。示例代码:
<Button> <Button.Content> <Rectangle Height="140" Width="40" Fill="Black"/> </Button.Content> </Button> |
Content属性被设置为一个XML Element而不是XML Attribute。这也是属性元素这个名称的由来。属性元素以"类型名.属性名"形式表示,如Button.Content,其中"."分割对象名与属性名。这个表示类型属性的名称将作为元素出现,且这个元素没有自己的特性。
上述XAML属性元素的表示,与如下所示的C#代码作用相同:
System.Windows.Controls.Button b = new Button(); System.Windows.Shapes.Rectangle r = new Rectangle(); r.Width = 40; r.Height = 40; r.Fill = System.Windows.Media.Brushes.Black; b.Content = r; |
属性元素中也可以设置简单的属性值,如下:
<Button> <Button.Content> OK </Button.Content> </Button> |
上面这种写法只是来演示属性元素,实际应用中还是会以如下传统Attribute的方式书写:
<Button Content="OK" ></Button> |
应用:属性元素多用于设置Content,Background等接受复杂对象的属性。
最后给出一个设置Background属性的属性元素应用的示例:
<Button> <Button.Background> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
|