WPF中的Attached Property
Attached Property是Dependency Property的一种特殊形式,它是用DependencyProperty.RegisterAttached方法注册的,可以被有效地添加到任何继承自DependencyObject的对象中,所以被称为Attached Property。一开始,这可能听起来很奇怪,但这种机制在WPF中有很多种应用。
首先,我们先看看Attached Property的定义,以TextElement的FontSizeProperty为例:
public static readonly DependencyProperty FontSizeProperty;
FontSizeProperty = DependencyProperty.RegisterAttached(
"FontSize", typeof(double), typeof(TextElement), new FrameworkPropertyMetadata(
SystemFonts.MessageFontSize, FrameworkPropertyMetadataOptions.Inherits |
FrameworkPropertyMetadataOptions.AffectsRender |
FrameworkPropertyMetadataOptions.AffectsMeasure),
new ValidateValueCallback(IsValidFontSize));
Attached Property的注册和Dependency Property很相似,区别在于是用RegisterAttached还是用Register方法注册。
对Attached Property的访问,通过Static函数来实现。
public static double GetFontSize(DependencyObject element)
{
element.GetValue(FontSizeProperty);
}
public static void SetFontSize(DependencyObject element, double value)
{
element.SetValue(FontSizeProperty, value);
}
一般来说,Attached Property不会使用.NET属性包装器进行包装。而且,实现Attached Property的类,并未调用自己的SetValue/GetValue方法,因此,实现Attached Property的类不需要继承自DependencyObject。
下面的示例显示在XAML中设置Attached Property:
<StackPanel TextElement.FontSize="30">
<Button Content="I'm a Button!"/>
</StackPanel>
StackPanel自己没有任何与字体有关的属性,如果要在StackPanel上设置字体大小,那么需要使用TextElement的FontSize Attached Property。当XAML解析器或编译器遇到TextElement.FontSize这样的语法时,它会去调用TextElement(Attached Property提供者)的SetFontSize函数,这样它们才能设置相应的属性值。另外,与普通的Dependency Property一样,这些GetXXX和SetXXX方法只能调用SetValue/GetValue方法,不能挪作他用。
接下来,我们说说Attached Property的用途。
Attached Property属性的一个用途是允许不同的子元素为实际在父元素中定义的属性指定唯一值。此方案的一个具体应用是让子元素通知父元素它们将如何在用户界面 (UI) 中呈现。派生自Panel的各种类定义了一些Attached Property,用来把它们添加到子元素上来控制它们的摆放。通过这种方式,每个Panel可以把自定义行为给任何一个子元素,而不需要所有的子元素都具有自己的相关属性集。
Attached Property属性的另一个用途是可以作为一种扩展机制。即可以用Attached Property高效地向密封类的实例添加自定义数据。另外,Attached Property是Dependency Property,因此,可以把任何一个Dependency Property作为一个Attached Property。如果对实例进行了扩展,则SetValue设定的值是储存在实例中的,可以通过GetValue获得。