从源码角度解析依赖属性

什么是依赖属性?

依赖属性是属性的全新实现,它是在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属性了。

Guess you like

Origin blog.csdn.net/q913777031/article/details/116304241