XAML的DependencyProperty

Wed 10 July 2019 / In categories Library

WinRT, XAML

DependencyObject和DependencyProperty意欲为何。

把代码这种编译器专用数据变为XAML这种更通用数据有诸多好处,但也有非常明显的坏处。代码在被解析的时候,各种值的类型为编译器所熟知;但是转化为XAML数据之后,XAML解释器可能猜不出元素所代表的类型。打个比方,如果你把一道鱼香肉丝拍成照片,可以让大家随时随地浏览,但照片毕竟不是真正的鱼香肉丝,看照片的人是闻不到鱼香肉丝的味道的。那怎么才能让看鱼香肉丝照片的人能够知道鱼香肉丝什么味道呢?一种做法是做一种鱼香肉丝味道的口香糖。让大家在看照片的时候嚼口香糖,然后振振有词道:看,这就是鱼香肉丝,尝,这就是鱼香肉丝。

把代码书写的对象使用XAML的元素来描述,就有点给这些对象照相的感觉。只能看到相片中的模样,而没有真实的触感。比如说TextBlock有FontFamily、FontSize和FontStyle等权属。你也可以在XAML中指定这些元素的值:

<TextBlock FontSize="48"> Hello </TextBlock>

上面的XAML片段会生成一个TextBlock对象,但是XAML并不知道这个对象有一个FontSize权属,所以上面的代码并不相当于:

txtblk.FontSize = 48

上面的代码需要知道TextBlock有一个字段作为其权属,可以被复制。但是XAML并不知道这个信息。

在XAML中,<TextBlock FontSize="48">其实被转译成了:

txtblk.SetValue(TextBlock.FontSizeProperty, 48)

在XAML严重,TextBlock其实是一个DependencyObject,有若干DependencyProperty

而DependencyProperty和一般的权属不一样,它是储存在全局结构中的,而不是某个类对象的私有属性。DependencyProperty需要在类级别注册,下面是一个来自Dependency properties overview的例子:

// IsSpinningProperty is the dependency property identifier
// no need for info in the last PropertyMetadata parameter, so we pass null
public static readonly DependencyProperty IsSpinningProperty =
    DependencyProperty.Register(
        "IsSpinning", typeof(Boolean),
        typeof(ExampleClass), null
    );
// The property wrapper, so that callers can use this property through a simple ExampleClassInstance.IsSpinning usage rather than requiring property system APIs
public bool IsSpinning
{
    get { return (bool)GetValue(IsSpinningProperty); }
    set { SetValue(IsSpinningProperty, value); }
}

在XAML眼里,一个TextBlock不过是一个注册了若干DenpendencyProperty的DependencyObject而已。XAML并不需要知道它是一个TextBlock,而只需通过TextBlock全局注册的DenpendencyProperty就可以知道它支持什么样的属性。所以XAML需要的,不过是TextBlock打印在DependencyObject这张相纸上的照片。

(完)

Load Disqus Comments