参考资料:

一站式WPF--依赖属性(DependencyProperty)一

一站式WPF--依赖属性(DependencyProperty)二

        依赖属性之我见

这两篇文章介绍的了依赖属性的本质和由来,挺清晰的。

自我理解:依赖属性,说明有两个关系,依赖和属性。

依赖的由来:

在面向对象的世界里,属性大量存在,比如Button,就大约定义了70-80个属性来描述其状态。那么属性的不足又在哪里呢?

  当然,所谓的不足,要针对具体环境来说。拿Button来讲,它的继承树是Button->ButtonBase->ContentControl->Control->FrameworkElement->UIElement->Visual->DependencyObject->…

  每次继承,父类的私有字段都被继承下来。当然,这个继承是有意思的,不过以Button来说,大多数属性并没有被修改,仍然保持着父类定义时的默认值。通常情况,在整个Button对象的生命周期里,也只有少部分属性被修改,大多数属性一直保持着初始值。每个字段,都需要占用4K等不等的内存,这里,就出现了期望可以优化的地方:

  • 因继承而带来的对象膨胀。每次继承,父类的字段都被继承,这样,继承树的低端对象不可避免的膨胀。
  • 大多数字段并没有被修改,一直保持着构造时的默认值,可否把这些字段从对象中剥离开来,减少对象的体积

有了以上的背景,依赖就出现了,微软设计了DependencyProperty类, 里面有着 public static DependencyProperty Register(string name, Type propertyType, Type ownerType, object defaultValue)方法来注册属性。然后又定义了一个DependencyObject的基类来消费这个属性。这样继承自DenpendencyObject的类就可以注册自己的依赖属性,属性是自己注册的,其实严格的说并不是自己的,所以节省了空间。注册的属性在DependencyProperty里面通过一个hash( internal static Dictionary<object, DependencyProperty> RegisteredDps = new Dictionary<object, DependencyProperty>())来维护。注册过的属性都存在这个hash里面。自此依赖我感觉的由来就清楚了,不是自己的属性,而是此属性要依赖于DependencyProperty的。

依赖解释好了,那属性呢?其实属性就是对外暴漏接口罢了,注册依赖属性后就是给依赖属性赋值(set),或者问依赖属性取值(get),这些操作封装到了DependencyObject类里面,所有用过的属性的值都通过 List<EffectiveValueEntry> _effectiveValues = new List<EffectiveValueEntry>()来存储和维护。这样就不会污染最初的默认value。这里也就实现了某个属性变化的过程都可以DependencyObject里面的effectiveValues找到痕迹,这样也就支持了动画。获取和赋值都是通过EffectiveValueEntry这个入口来获得的。就此依赖属性设计好了。

这样的设计听好了,但是我们想要求子类也有自己的默认属性,比如很多控件都有Name属性,但有时候并不希望大家的默认值是一样的,但是有共用同一个DP。这该怎么解决呢?

要想支持不同的默认值,那么内部就要维护一个对应不同DependencyObjectType的一个List,可以根据传入的DependencyObject的类型来读取它对应的默认值。DP内需要维护一个自描述的List,按照微软的命名规则,添加新的类型属性元数据(PropertyMetadata)。其实在DependencyProperty里面添加了private List<PropertyMetadata> _metadataMap = new List<PropertyMetadata>();来维护元数据,实现对默认值的修改。

附加属性之我见:说白了就是依赖属性的改造,只是封装不同,区别在于附加二字,其实就是有些对象不具备某些属性,有些对象具备这些属性,那么具备这些依赖属性的对象就可以某些属性附加到不具备这些属性的对象上。比如人没有年级,班级的属性,而学校有年级班级的属性,但是当人在学校学习的时候就具备了班级年级的属性,这个时候学校这个对象就可以附加给人这个对象班级年级的属性。这就是附加属性。

回想下依赖属性,依赖属性是对一个对象来说的,这个对象可以注册依赖属性,以后这个对象就具备了这个属性。而附加属性是对两个对象来说的,一个是附加对象,一个是被附加对象。是不是可以这样理解,附加对象给被附加对象注册了一个依赖属性罢了。但这个依赖属性依靠附加对象操作。自己的理解不知道正确与否。

往更深层次的,就看看开头两篇的博客吧。

WPF之依赖属性和附加属性的更多相关文章

  1. WPF的依赖属性和附加属性(用法解释较全)

    转:https://www.cnblogs.com/zhili/p/WPFDependencyProperty.html 一.引言 感觉最近都颓废了,好久没有学习写博文了,出于负罪感,今天强烈逼迫自己 ...

  2. WPF 之 依赖属性与附加属性(五)

    一.CLR 属性 ​ 程序的本质是"数据+算法",或者说用算法来处理数据以期得到输出结果.在程序中,数据表现为各种各样的变量,算法则表现为各种各样的函数(操作符是函数的简记法). ...

  3. WPF依赖属性(续)(2)依赖属性与附加属性的区别

    原文:WPF依赖属性(续)(2)依赖属性与附加属性的区别        接上篇,感谢各位的评论,都是认为依赖属性的设计并不是为了节省内存,从大的方面而讲是如此.样式,数据绑定,动画样样都离不开它.这篇 ...

  4. WPF的依赖属性

    Windows Presentation Foundation (WPF) 提供了一组服务,这些服务可用于扩展公共语言运行时 (CLR)属性的功能,这些服务通常统称为 WPF 属性系统.由 WPF 属 ...

  5. [转]WPF的依赖属性是怎么节约内存的

    WPF升级了CLR的属性系统,加入了依赖属性和附加属性.依赖属性的使用有很多好处,其中有两点是我认为最为亮眼的: 1)节省内存的开销; 2)属性值可以通过Binding依赖于其它对象上,这就使得我的数 ...

  6. wpf 的依赖属性只能在loaded 事件之后才能取到

    wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的  InitializeComponent(); 之后取不到 wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的  ...

  7. WPF 中依赖属性的继承(Inherits)

    WPF中依赖属性的值是是可以设置为可继承(Inherits)的,这种模式下,父节点的依赖属性会将其值传递给子节点.例如,数据绑定中经常使用的DataContextProperty: var host ...

  8. XAML实例教程系列 - 依赖属性和附加属性(四)

    XAML实例教程系列 - 依赖属性和附加属性 2012-06-07 13:11 by jv9, 1479 阅读, 5 评论, 收藏, 编辑 微软发布Visual Studio 2012 RC和Wind ...

  9. WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性

    原文:WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性 如果你要自定义一个图片按钮控件,那么如何在主窗体绑定这个控件上图片的Source呢? ...

随机推荐

  1. PHP Redis 对象方法手册

    redis(Remote Dictionary Server)是一种Nosql技术,它是一个开源的高级kv存储和数据结构存储系统. redis不仅仅是能够存储key和value这种简单的键值对,还能存 ...

  2. mongodb通过profile来监控数据

    mongodb可以通过profile来监控数据,进行优化.查看当前是否开启profile功能用命令db.getProfilingLevel() 返回level等级,值为0|1|2,分别代表意思:0代表 ...

  3. UVA11137 Ingenuous Cubrency 完全背包 递推式子

    做数论都做傻了,这道题目 有推荐,当时的分类放在了递推里面,然后我就不停的去推啊推啊,后来推出来了,可是小一点的数 输出答案都没问题,大一点的数 输出答案就是错的,实在是不知道为什么,后来又不停的看, ...

  4. shell编程学习笔记(一):编写我的第一段代码

    目前在学习Shell编程,我会把我的学习笔记记录在这里.大神可以直接略过~ 嗯,第一段代码,肯定是要输出Hello World了~ 以下蓝色字体的内容为linux命令,红色字体的内容为输出的内容: # ...

  5. Windows 下使用 MinGW 和 CMake 进行开发

    CMake 是个非常棒的项目管理工具,这已经是毋庸置疑的. 一些小工具需要在 win 下开发,所以今天探索使用 MinGW 和 CMake 在 win 下的搭配使用.简单做记录. MinGW 使用 Q ...

  6. 在Android上启用Kiosk模式

    我们的云帆机器人(上面运行的安卓程序)有一个线下场景是商场,由于商场人多,总会遇到一些用户在我们的app里乱点,然后会跳出程序进入到系统设置的一些界面,这样很不友好. 比如程序中有一些需要输入文字的地 ...

  7. C#:网络传输问题

    1.Http Post Header 中文数据值,服务端接收Header 中文数据值乱码问题: 客户端:    Encoding utf8Encoding = Encoding.GetEncoding ...

  8. CountDownLatch、CyclicBarrier及Semaphore的用法示例

    一.参考blog https://www.cnblogs.com/dolphin0520/p/3920397.html 二.CountDownLatch 个人把它类比于一个持有计数的闸门,每到达这个闸 ...

  9. 第三部分:Android 应用程序接口指南---第五节:计算---第一章 RenderScript

    第1章 RenderScript RenderScript提供一个独立于平台并在本地运行的计算引擎,用它来加速你需要大量计算能力的应用.RenderScript是一个运行与Android上计算密集型的 ...

  10. oracle中decode的用法(例子)

    使用结构: decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下: IF 条件=值1 THEN RETURN(翻译值1)ELSIF 条件=值2 THEN ...