来自《深入浅出WPF》(刘铁猛)读书笔记
附加属性(Attached Properties)
一个属性本来不属于某个对象,但由于某种需求而被后来附加上。也就是把对象放入一个特定环境后对象才具有的属性,表现出来就是被环境赋予的属性。
附加属性的作用是将属性与数据类型(宿主)解耦,让数据类型的设计更加灵活。
附加属性声明时一样使用public static readonly三个关键字共同修饰,唯一不同就是注册附加附加属性使用的是RegisterAttached方法,但参数却与使用Register方法无异。附加属性的包装器也与依赖属性不同--依赖属性使用CLR属性对GetValue和SetValue两个方法进行包装,附加属性则使用两个方法分别进行包装。
准备学校和人类:
class School:DependencyObject
{
public static int GetGrade(DependencyObject obj)
{
return (int)obj.GetValue(GradeProperty);
}
public static void SetGrade(DependencyObject obj, int value)
{
obj.SetValue(GradeProperty,value);
}
public static readonly DependencyProperty GradeProperty = DependencyProperty.RegisterAttached("Grade",typeof(int),typeof(School),new UIPropertyMetadata(0));
}
如何消费School的GradeProperty?首先准备一个派生自DependencyObject,名为Human的类:
class Human: DependencyObject
{
}
在UI上准备一个Button并添加Click事件的处理器:
private void Button_Click(object sender, RoutedEventArgs e)
{
Human human=new Human();
School.SetGrade(human,6);
int grade=School.GetGrade(human);
MessageBox.Show(grade.ToString());
}
另一个实例,XAML代码:
<Button Content="OK" Grid.Column="1" Grid.Row="1" />
对应的C#代码:
Button button=new Button() {Content="OK");
Grid.SetColumn(button,1);
Grid.SetRow(button,1);
附加属性本质是依赖属性--也可以使用Binding依赖在其他对象的数据上。
窗体使用Canvas布局,两个Slider用来控制矩形在Canvas中的纵横坐标,实现这个需求的XAML代码:
<Canvas>
...
<Rectangle x:Name="rect" Fill="Blue" Width="30" Height="30"
Canvas.Left="{Binding ElementName=sliderX,Path=Value}"
Canvas.Top="{Binding ElementName=sliderY,Path=Value}" />
</Canvas>
与之等效的C#代码(仅Binding部分):
//Binding setting
this.rect.SetBinding(Canvas.LeftProperty,new Binding("Value") {Source=sliderX});
this.rect.SetBinding(Canvas.TopProperty,new Binding("Value") {Source=sliderY});