XAML中,关于特性语法部分,讲到了一个很重要的知识点——类型转换器。经过几天的啃书(WPF揭秘、XAML概述、XAML语法详述)+攻关,慢慢开始理解了该XAML语法概念和用法,现总结如下:

     先来看类型转换的概念:

    特性语法中讲到,特性值(属性或事件)必须为双引号扩起来的纯文本形式的字符串,亦或者是Double等其他基元值,对于XAML处理器来说,都是本文字符串。

如果该值既不是分析器所能识别的基元,也不是枚举,则所涉及的类型必须能够根据转换的字符串提供该类型的实例(即XAML标记中该属性的字符串值必须满足后台对应属性的值类型的构造函数,能否生成对应值类型的实例)。 这个时候,就是依靠类型转换器来实现此功能,这就是类型转换的概念。

   那WPF是如何实现将XAML中属性的字符串值转换为后台属性的值类型实例呢?其机理是什么?我们来看个示例。

<Button Margin="10,20,10,30" Content="Click me" />

   Button元素对象有一个Margin属性,用来设置元素的外边距,Margin属性在后台映射为FrameworkElement.Margin 属性,其C#语法定义为:

public Thickness Margin { getset; }

 

    这里我们看到Margin属性的值类型为Thickness,我们继续在MSDN中查一下Thickness类的定义,得知:Thickness为一结构类型,用于Bottom)。 其语法定义为:

[LocalizabilityAttribute(LocalizationCategory.None, Readability = Readability.Unreadable)]
[TypeConverterAttribute(typeof(ThicknessConverter))]
public struct Thickness : IEquatable<Thickness>

    我们看到Thickness类是由TypeConvertAttribute特性类来声明的,即在实例化Thickness实例对象时,指定了通过ThicknessConverter类型转换器来实现其他类型对象实例与Thickness类型实例对象之间的转换。根据上面XAML标记中Margin特性值为“10,20,10,30”,正好与Thickness的LeftTopRightBottom四个属性值对应。据此,XAML解析器对Margin特性的字符串值在后台进行类型转换,由ThicknessConverter类型转换器返回Thickness对象实例。

    在MSDN中,直接说明了Margin属性的XAML 属性元素用法XAML 特性用法

<object>
  <object.Margin>
    <Thickness Left="left" Top="top" Right="right" Bottom="bottom"/>
  </object.Margin>
</object>
<object Margin="left,top,right,bottom"/>
- or -
<object Margin="left,top"/>
- or -
<object Margin="thicknessReference"/>

 

     通过以上示例,我们可以看出,如果采用属性元素用法,标记代码要冗长得多,而采用特性用法,则简化很多。因此,我们可以总结出,类型转换器实际上用于XAML中的类型转换行为,正是因为属性的值类型Thickness提供了ThicknessConverter类型转换器,我们才能简化设置Margin属性值。这就是类型转换器的工作原理。

   

 

 

相关文章: