WPF之依赖属性和附加属性
参考资料:
一站式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之依赖属性和附加属性的更多相关文章
- WPF的依赖属性和附加属性(用法解释较全)
转:https://www.cnblogs.com/zhili/p/WPFDependencyProperty.html 一.引言 感觉最近都颓废了,好久没有学习写博文了,出于负罪感,今天强烈逼迫自己 ...
- WPF 之 依赖属性与附加属性(五)
一.CLR 属性 程序的本质是"数据+算法",或者说用算法来处理数据以期得到输出结果.在程序中,数据表现为各种各样的变量,算法则表现为各种各样的函数(操作符是函数的简记法). ...
- WPF依赖属性(续)(2)依赖属性与附加属性的区别
原文:WPF依赖属性(续)(2)依赖属性与附加属性的区别 接上篇,感谢各位的评论,都是认为依赖属性的设计并不是为了节省内存,从大的方面而讲是如此.样式,数据绑定,动画样样都离不开它.这篇 ...
- WPF的依赖属性
Windows Presentation Foundation (WPF) 提供了一组服务,这些服务可用于扩展公共语言运行时 (CLR)属性的功能,这些服务通常统称为 WPF 属性系统.由 WPF 属 ...
- [转]WPF的依赖属性是怎么节约内存的
WPF升级了CLR的属性系统,加入了依赖属性和附加属性.依赖属性的使用有很多好处,其中有两点是我认为最为亮眼的: 1)节省内存的开销; 2)属性值可以通过Binding依赖于其它对象上,这就使得我的数 ...
- wpf 的依赖属性只能在loaded 事件之后才能取到
wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的 InitializeComponent(); 之后取不到 wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的 ...
- WPF 中依赖属性的继承(Inherits)
WPF中依赖属性的值是是可以设置为可继承(Inherits)的,这种模式下,父节点的依赖属性会将其值传递给子节点.例如,数据绑定中经常使用的DataContextProperty: var host ...
- XAML实例教程系列 - 依赖属性和附加属性(四)
XAML实例教程系列 - 依赖属性和附加属性 2012-06-07 13:11 by jv9, 1479 阅读, 5 评论, 收藏, 编辑 微软发布Visual Studio 2012 RC和Wind ...
- WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性
原文:WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性 如果你要自定义一个图片按钮控件,那么如何在主窗体绑定这个控件上图片的Source呢? ...
随机推荐
- Zookeeper学习笔记——1 单机版本环境搭建
下载 首先去官网下载: http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.11/ 然后执行tar -zxvf解压 启动 进入conf目录, ...
- Comparison method violates its general contract 解决
java.lang.IllegalArgumentException: Comparison method violates its general contract! 原因 JDK7中的Collec ...
- 使用jetty工具包处理url参数成map
引入工具包: <dependency> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-u ...
- SublimeText SFTP连接Amazon EC2
文章最初发表于szhshp的第三边境研究所 转载请注明 1. SublimeText SFTP连接Amazon EC2 Sublime Text 3 正式版发布了,全平台IDE果断都换了. 今天终于有 ...
- Android Gesture Detector
Android Touch Screen 与传统Click Touch Screen不同,会有一些手势(Gesture),例如Fling,Scroll等等.这些Gesture会使用户体验大大提升.An ...
- 【ZH奶酪】如何用Python计算最长公共子序列和最长公共子串
1. 什么是最长公共子序列?什么是最长公共子串? 1.1. 最长公共子序列(Longest-Common-Subsequences,LCS) 最长公共子序列(Longest-Common-Subseq ...
- PRTG安装
1.去官网下载,记录下试用秘钥,然后执行安装 2. 3. 4.输入秘钥 5. 6.安装完成后自动转到如下页面,点击启动Guru 7. 8. 9. 10.输入prtgadmin,密码prtgadmin ...
- Win10更新搜狗输入法后重启输入密码蓝屏
解决办法:如果能进入安全模式,卸载搜狗输入法:不行的话(好像不行)只能重装系统:因为蓝屏后就基本开不了了!!!生气!! win10 1809 19.3月累积更新之后蓝屏:安装了搜狗输入法的win10 ...
- UICollectionView在初始化的时候移动到某个距离
#pragma mark -- 使用场景:选中非第一张图片用CollectionView进行浏览时,CollectionView滑动到对应的位置 #pragma mark -- 重点在于UICol ...
- 12C -- ORA-12850: 无法在所有指定实例上分配从属进程: 需要 2, 已分配 1
使用客户端连接到oracle 12.2.0.1 rac数据库,报以下错误信息: ORA-12850: 无法在所有指定实例上分配从属进程: 需要 2, 已分配 1 因为没有mos账号,只好谷歌一下了.找 ...