来自《深入浅出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});