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呢? ...
随机推荐
- oracle data integrator与大数据平台的集成
在最新版本的ODI中,通过使用各种知识模块,可在统一的界面上实现对传统数据库.hive, pig, spark, hdfs等的ETL操作,满足在同一系统或采用相同的方式实现ETL功能. 详细的内容可参 ...
- mac pro 如何让终端默认运行python3.X而不是2.7
Mac版本的Python默认是2.7,安装高版本后需要修改为你安装的版本. 1,首先打开终端 open ~/.bash_profile 打开配置文件 2. 写入python的外部环境变量(本人的版本是 ...
- Window Server 2008 R2 TFS2010 安装前的准备
前言 http://www.cnblogs.com/aehyok/p/3979707.html 这里简单介绍了安装windows Server 2008 R2系统,接下来就开始介绍安装Team Fou ...
- 【React】入门实例
React 可以灵活的应用在各种各样的项目中.你可以用它来创建新的应用程序,你也可以逐步引用而不改变现有的代码库. React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaS ...
- 【MySQL】玩转触发器、监听器
1.触发器是一个特殊的存储过程,不同的是存储过程要用CALL来调用,而触发器不需要使用CALL. 创建触发器 语法如下: CREATE TRIGGER trigger_name trigger_tim ...
- ios中输入框的父类--文本框,DataPick,pickerview
父控制器 #import <UIKit/UIKit.h> #import "ScrollViewExt.h" @interface BaseKeyBoardCtrl : ...
- java 对一个字符串进行加减乘除的运算
记录一个小程序,里面涉及到的JAVA知识点有:字符串扫描,list删除元素的方法,泛型的使用,JAVA中的/要注意的事项.有兴趣的可以看看 package com.demo; import java. ...
- maven打包含有多个main程序的jar包及运行方式
pom.xml <build> <plugins> <plugin> <groupId> ...
- SpringCloud服务间调用
SpringCloud服务间的调用有两种方式:RestTemplate和FeignClient.不管是什么方式,他都是通过REST接口调用服务的http接口,参数和结果默认都是通过jackson序列化 ...
- OpenCV 学习笔记 06 SIFT使用中出现版权问题error: (-213:The function/feature is not implemented)
1 错误原因 1.1 报错全部信息: cv2.error: OpenCV(4.0.1) D:\Build\OpenCV\opencv_contrib-4.0.1\modules\xfeatures2d ...