什么是依赖属性?
依赖属性是属性的全新实现,它是在C#属性的基础上包装而成。
通俗理解:自己没有值,通过绑定的数据源 来获取值,依赖别的对象来传值,依赖属性的对象称为依赖对象。
从源码盘它
我们从system.windows 源码,可以注意到因为DependencyProperty类没有公有
的构造函数。反而只能使用静态的DependencyProperty.Register()方法创建
那我们看看最复杂的Register方法,可以看到有属性名Name,属性类型,拥有者类型,以及默认元数据值以及验证回调函数。
我们也可以观察到它调用了个RegisterCommon
方法,进行了简单的传参,我们继续看看这个方法。
它的第一步是实例化了FromNameKey
的对象,继续看
可以看到,它是根据拥有者类型名和属性名生成了一个HashCode,那这个类就是用来生成HashCode的。生成来干嘛呢?我们去看看,可以看到是PropertyFromName
的哈希表调用Contains方法来判断是否包含当前属性生成的HashCode,不包含则将key放入哈希表中。
并调用了ValidateMetadataDefaultValue回调方法进行了验证以及生成默认值。
总结
依赖属性优势
对比属性,依赖属性主要有以下三个优点:
- 方便:依赖属性加入了属性变化通知、限制、验证等功能。
- 节约内存:在WinForm中,每个UI控件的属性都赋予了初始值,这样每个相同的控件在内存中都会保存一份初始值。而WPF依赖属性很好地解决了这个问题,它内部实现使用哈希表存储机制,对多个相同控件的相同属性的值都只保存一份。
- 支持多种提供对象:可以通过多种方式来设置依赖属性的值。可以配合表达式、样式和绑定来对依赖属性设置值。
注意: 只能为依赖对象(继承自DependencyObject的类)添加依赖项属性。幸运的是,WPF基础结构的关键部分中的大部分都间接继承自DependencyObject类,最明显的例子就是元素。
使用方式:
当我们使用依赖属性的时候,我们可以这样通过调用Register将依赖属性注入到HashTable中。
编码技巧:Visual Studio中输入propdp 然后按Tab自动生成
此处示例SearchText,假设我们需要在控件内添加一个SearchText依赖属性
注册
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SearchTextProperty =
DependencyProperty.Register("SearchText", typeof(string),
typeof(SearchTextBox), new PropertyMetadata(""));
我们需要提供这些参数:
- 属性名(在该示例中为SearchText)
- 属性使用的数据类型(在该示例中为string)
- 拥有该属性的类型(在该示例中为SearchTextBox类)
- 一个具有附加属性设置的FrameworkPropertyMetadata对象,该要素是可选的
- 一个用于验证属性的回调函数,该要素是可选的
添加属性包装器
public string SearchText
{
get => (string) GetValue(SearchTextProperty);
set => SetValue(SearchTextProperty, value);
}
至此,我们可以在定义的控件上可以正常使用SearchText属性了。