传统的.NET的开发中,一个对象所占用的内存空间在调用new操作符进行实例化的时候就已经决定了,而WPF允许对象在被创建的时候并不包含用于存储数据的
空间(即字段所占用的空间)、只保留在需要用到数据时能够获得默认值、借用其他对象数据或实时分配空间的能力——这种对象就称为依赖对象,而它这种实时
获取数据的能力则依靠依赖属性来实现。
一.声明和使用依赖属性
<Window x:Class="MyProperty.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="130" Width="250"> <Grid> <StackPanel> <TextBox x:Name="textBox1" BorderBrush="Black" Margin="5" Height="25"/> <TextBox x:Name="textBox2" BorderBrush="Black" Margin="5" Height="25"/> <Button Content="OK" Margin="5" Click="Button_Click"/> </StackPanel> </Grid> </Window>
DependencyProperty必须以DependencyObject为宿主,借助它的SetValue和GetValue方法进行写入和读取,因此,想使用自定义的DependencyProperty,宿主一定是DependencyObject的派生类,
DependencyProperty的实例的声明特点很鲜明——引用变量由public static readonly三个修饰符修饰,实例并非使用new操作符得到而是使用DependencyProperty.Register方法生成,代码如下:
namespace MyProperty { public class Student:DependencyObject { //CLR属性包装器 private string _name; 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); } }
(1).第一个参数为string类型,用这个参数来指明以哪个CLR属性作为这个依赖属性的包装器,或者说此依赖属性支持的是哪个CLR属性
(2).第二个参数用来指明此依赖属性用来存储什么类型的值,学生的姓名是string类型,所以是这个参数被赋值为typeof(string)
(3).第三个参数用来指明此依赖属性的宿主是什么类型,或者说DependencyProperty.Register方法将把这个依赖属性注册关联到哪个类型上,上例中
是为Student类准备一个可依赖的名称属性,所以需要把NameProperty注册成与Student关联,因此这个参数被赋值为typeof(Student)
然后,我们使用Binding把Student对象关联到textBox1上,再把textBox2关联到Student对象上形成Binding链,代码如下:
namespace MyProperty { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Student stu = new Student(); stu.SetBinding(Student.NameProperty, new Binding("Text") { Source = textBox1 }); textBox2.SetBinding(TextBox.TextProperty, new Binding("Name") { Source = stu }); } } }