依赖属性
简介
依赖属性就是自己本身没有值,可以通过binding获取到数据源的值。具有依赖属性的对象称为依赖对象,依赖对象包含一般的控件(TextBox.text或ListBox.ItemsSourceProperty就是一个典型的依赖属性),也包含从有依赖属性的类生成的对象(后面会举例说明)。
优点
节省内存空间。
每个CLR属性都包含一个非static的字段,如果一个实例具有多个属性,创建实例数目多的话,占用内存较大。
CLR属性:
public class Human
{
private int age;
public int Age
{
get
{
return this.age;
}
set
{
if (value >= 0 && value <= 100)
{
this.age = value;
}
else
{
throw new OverflowException("Age overflow");
}
}
}
}
而依赖属性允许对象在创建的时候并不包含用于存储数据的空间,只保留在需要用到数据的时候能够获得该默认值,即用其他对象数据或者实时分配空间的能力。
在依赖属性实现的过程中,依赖对象通过DependencyObject实现,依赖属性的由DependencyProperty实现,DependencyObject中存在SetValue方法和GetValue方法,参数为dependencyProperty。依赖对象和依赖属性相结合才能实现依赖属性的效果。
实现流程
1、创建一个依赖属性(通过DependencyProperty.Register()方法来注册)
2、创建一个CLR属性(CLR属性中用SetValue方法和GetValue方法继承于DependencyObject类,参数为依赖属性)
3、做一个SetBinding包装,这样包装之后可以用Student.setbinding()的方法来设置binding,符合我们一般的书写习惯
4、设置binding
备注:1、没有实现INotifyPropertyChanged接口,就可以实现数据变化就在UI上呈现,依赖属性默认就有这样的功能。
2、为啥dependencyProperty前面要用static readonly来修饰????具体解答在《WPF深入浅出》7.2.3节,但我为啥看不了DependencyProperty类的方法的源码呢??
依赖属性样例
动态展示
代码
XAML:
<StackPanel>
<TextBox Name="text1" Margin="10"/>
<TextBox Name="text2" Margin="10"/>
<Button Name="button1" Click="button1_Click" Content="刷新"/>
</StackPanel>
主程序代码:
public partial class MainWindow : Window
{
Student student = new Student();
public MainWindow()
{
InitializeComponent();
Binding binding = new Binding("Text") { Source = this.text1 };
student.SetBinding(Student.dependencyProperty, binding);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Binding binding = new Binding("Name") { Source = student };
this.text2.SetBinding(TextBox.TextProperty, binding);
}
}
数据源及依赖属性的设置:
class Student : DependencyObject
{
//创建一个依赖属性
public static readonly DependencyProperty dependencyProperty =
DependencyProperty.Register("Name", typeof(String), typeof(Student));
//创建一个CLR属性
public String Name
{
set
{
SetValue(dependencyProperty, value);
}
get
{
return GetValue(dependencyProperty) as String;
}
}
//SetBinding包装,这样包装之后可以用Student.setbinding()的方法来设置binding,符合我们一般的书写习惯
public BindingExpressionBase SetBinding(DependencyProperty dependencyProperty, BindingBase bindingBase)
{
return BindingOperations.SetBinding(this, dependencyProperty, bindingBase);
}
}