依赖属性是一种自己可以没有值,并且通过Binding从数据源获得值的属性。拥有依赖属性的对象被称为依赖对象。与传统CLR属性和面向对象思想相比依赖属性有很多新颖,包括
- 节省实例对内存的开销
- 属性值可以通过Binding依赖在其他对象上
1.1.依赖属性对内存的使用方式
在传统NET开发中,一个对象所占用的内存空间在调用NEW操作符进行实例化的时候就已经决定了,
WPF允许对象在被创建的时候并不包含用于存储数据的空间,只保留在需要用到数据时能够获得默认值借用其他对象数据或实时分配空间的能力
WPF的所有UI控件都是依赖对象,UI控件的绝大多数属性都已经被依赖化。
WPF开发中需要依赖对象作为依赖属性的宿主,才能形成完整的Binding目标被数据驱动
1.2.声明和使用依赖属性
声明
public class Student:DependencyObject { public static readonly DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Student)); }
由于依赖属性需以DependencyObject为宿主,借助它的SetValue和GetValue进行读写,宿主必须继承DependencyObject,如下Student;
依赖属性实例通过DependencyProperty.Register进行注册声明,而不是New,且被static readonly修饰
使用 <Window x:Class="WPF.DependencyPropertyTest" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="DependencyProperty" Height="300" Width="600"> <StackPanel> <TextBox x:Name="textBox1" BorderBrush="Black" Margin="5"/> <TextBox x:Name="textBox2" BorderBrush="Black" Margin="5"/> <Button Content="Ok" x:Name="buttonOk" Click="buttonOk_Click"/> </StackPanel> </Window> //后台代码 public DependencyPropertyTest() { InitializeComponent(); } private void buttonOk_Click(object sender, RoutedEventArgs e) { Student stu = new Student(); stu.SetValue(Student.NameProperty, this.textBox1.Text);//依赖属性值的写入 textBox2.Text=(string)stu.GetValue(Student.NameProperty);//依赖属性值的读取
}
public class Student:DependencyObject { //利用属性包装器 public string Name { get { return (string)GetValue(NameProperty); } set { SetValue(NameProperty, value); } } public static readonly DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Student)); } //依赖属性就可以像普通属性一样读写访问 Student stu = new Student(); stu.Name=this.textBox1.Text;//依赖属性值的写入 textBox2.Text=stu.Name;//依赖属性值的读取
升级一下Student
public class Student:DependencyObject { //CLR属性包装器包装依赖属性的读写操作 public string Name { get { return (string)GetValue(NameProperty); } set { SetValue(NameProperty, value); } } //依赖属性 public static readonly DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Student)); //SetBinding包装 public BindingExpressionBase SetBinding(DependencyProperty dp, BindingBase binding) { return BindingOperations.SetBinding(this, dp, binding); } } <Window x:Class="WPF.DependencyPropertyTest" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="DependencyProperty" Height="300" Width="600"> <StackPanel> <TextBox x:Name="textBox1" BorderBrush="Black" Margin="5"/> <TextBox x:Name="textBox2" BorderBrush="Black" Margin="5"/> <Button Content="Ok" x:Name="buttonOk" Click="buttonOk_Click"/> </StackPanel> </Window> //后台代码 public partial class DependencyPropertyTest : Window { Student Stu; public DependencyPropertyTest() { InitializeComponent(); Stu = new Student(); Stu.SetBinding(Student.NameProperty, new Binding("Text") {Source=this.textBox1 }); this.textBox2.SetBinding(TextBox.TextProperty, new Binding("Name") { Source=Stu}); } }
注:visual sutdio创建依赖属性的快捷键propdp