依赖属性是一种可以从父级元素继承,并且可以通过Binding从数据源获取,当从父级继承时不占用内存的属性系统。拥有依赖属性的对象称为依赖对象。WPF允许在创建对象时并不分配用于存储数据的空间,而在需要时实时分配空间或直接借用父级数据,这种对象称为依赖对象(DependencyObject),这种实时获取数据的能力依靠依赖属性(Dependency Property)来实现。必须使用依赖对象作为依赖属性的宿主。DependencyObject是相当底层的一个基类,通过GetValue和SetValue获取或设置依赖属性的值。

声明和使用依赖属性

    public class Student:DependencyObject{public readonly static DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(String), typeof(Student));public String Name{get { return (String)GetValue(Student.NameProperty); }set { SetValue(Student.NameProperty, value); }}}

依赖属性一定被声明为public static readonly,并且约定依赖属性成员名称添加后缀“Property”表明这是一个依赖属性。依赖属性实例通过Register方法创建,Register的第一个参数为此依赖属性的CLR属性包装器的名称,第二个参数为依赖属性注册的类型,第三个参数为依赖属性的宿主类型。当依赖属性没有用CLR属性包装时,只能作为数据绑定的Target,使用CLR属性包装后,即可以作为Binding的Target,也可以作为Binding的Source。当依赖属性作为Binding的Source时,即使不实现INotifyPropertyChanged接口在属性值更改时也能通知Binding更改Target,依赖属性自带通知功能,因此当我们不想实现繁琐的INotifyPropertyChanged接口时可以使用依赖属性作为数据源。在Visual Studio中通过输入propdp在连按两次Tab键可以直接输入依赖属性模板,以加快编码速度。

依赖属性值存取的原理

创建一个DependencyProperty实例,并用它的CLR属性名和宿主类型名生成hash code,最后使用hash code作为DependencyProperty实例的key存入全局的名为DependencyProperty.PropertyFromName的Hashtable中。这样通过CLR属性名和宿主类型名检索出DependencyProperty实例,因此在同一个类型中不能声明CLR属性名相同的多个依赖属性实例。

依赖属性的值被统一存储在DependencyObject中的EffectiveValueEntry[] _effectiveValues这样的数组中,数组根据算法和DependencyProperty的GlobalIndex属性进行排序,依赖属性值的存取、删除、等操作都是针对这个数组进行,DependencyProperty的实例只是依赖属性值的标识,用来检索属性值。

附加属性

顾名思义,附加属性是说一个属性本来不属于某个类,但由于某种需求而被后来附加上。也就是说把对象放到一个特殊的环境中对象才有的属性。附加属性的作用就是让属性与数据类型解耦,让数据类型的设计更加灵活,附加属性定义在更高层次语义的对象上,在需要时附加到与之关联的对象上。附加属性本质上是依赖属性,二者仅在注册与包装器上有区别。

    public class School:DependencyObject{public static int GetGrade(DependencyObject obj){return (int)obj.GetValue(GradeProperty);}public static void SetGrade(DependencyObject obj, int value){obj.SetValue(GradeProperty, value);}// Using a DependencyProperty as the backing store for Grade.  This enables animation, styling, binding, etc...public static readonly DependencyProperty GradeProperty =DependencyProperty.RegisterAttached("Grade", typeof(int), typeof(School), new PropertyMetadata(0));}

声明附加属性时仅注册方法不同,参数和参数含义相同。附加属性的包装器与依赖属性不同,分别声明Get和Set方法用来存取附加属性,附加属性存取在要附加的对象上。实际上附加属性就是使用定义在其他类中的DependencyProperty存取属性值。附加属性的本质为依赖属性,因此可以使用Binding依赖其他对象的属性值。示例代码:

        <Slider x:Name="slider" Minimum="0" Maximum="100"></Slider><Canvas Width="200" Height="200" Background="Gray"><Rectangle x:Name="rect" Width="20" Height="20" Canvas.Left="{Binding ElementName=slider, Path=Value,Mode=OneWay}" Fill="Red"></Rectangle></Canvas>//等价的后台代码Binding binding = new Binding("Value");binding.ElementName = "slider";binding.Mode = BindingMode.OneWay;rect.SetBinding(Canvas.LeftProperty, binding);

转载于:https://www.cnblogs.com/jefflee/p/5822470.html

《深入浅出WPF》学习笔记之深入浅出话属性相关推荐

  1. 深入浅出WPF学习笔记之Binding

    深入浅出WPF之Binding Binding Binding基础 Binding模型 把控件作为Binding源与Binding标记扩展 Binding的(Path)路径 Binding支持多级路径 ...

  2. 《深入浅出WPF》笔记——绑定篇(一)

    上一节,有记录写到:在WPF里,数据驱动UI,数据占核心地位,UI次之.怎么恢复数据的核心地位,那就要先了解一下Binding. 一.Binding 基础 1.1WPF中Data Binding的带来 ...

  3. 《深入浅出WPF》笔记——事件篇

    如果对事件一点都不了解或者是模棱两可的话,建议先去看张子阳的委托与事件的文章(比较长,或许看完了,也忘记看这一篇了,没事,我会原谅你的)http://www.cnblogs.com/JimmyZhan ...

  4. 《深入浅出WPF》笔记——模板篇

    原文:<深入浅出WPF>笔记--模板篇 我们通常说的模板是用来参照的,同样在WPF中,模板是用来作为制作控件的参照. 一.认识模板 1.1WPF菜鸟看模板 前面的记录有提过,控件主要是算法 ...

  5. 深入浅出MFC学习笔记

    深入浅出MFC学习笔记 ithzhang CSDN博客:http://blog.csdn.net/ithzhang/article/category/1159054 转载于:https://blog. ...

  6. 深入浅出SSD 学习笔记整理——Johnathan Sung

    SSD ( Solid State Drive),即固态硬盘,是一种以半导体闪存( NAND Flash)作为介质的存储设备.和传统机械硬盘(Hard Disk Drive,HDD)不同,SSD以半导 ...

  7. 深入浅出DPDK学习笔记(3)——— Cache和内存

    深入浅出DPDK学习笔记(3)--- Cache和内存 系统架构的演进 Cache系统简介 Cache的种类 TLB Cache Cache地址映射和变换 全关联型Cache 直接关联型Cache 组 ...

  8. WPF学习笔记(数据绑定篇3)

    接上回的<WPF学习笔记(数据绑定篇2)>,继续 BindValidation 此示例演示了: 如何使用错误模板: 使用样式显示错误信息: 如何在校验发生异常时执行回调: 首先,你可以看见 ...

  9. WPF学习笔记(7):DataGrid中数字自定义格式显示

    WPF学习笔记(7):DataGrid中数字自定义格式显示 原文:WPF学习笔记(7):DataGrid中数字自定义格式显示 DataGrid中数据显示如下图,数据格式比较杂乱.希望达到以下要求:(1 ...

  10. 《MySQL实战45讲》——学习笔记04-05 “深入浅出索引、最左前缀原则、索引下推优化“

    04 | 深入浅出索引(上) 1. 什么是索引? 索引的出现其实就是为了提高数据查询的效率,就像书的目录一样,书有500页,每页存的都是书的内容,目录可能只有5页,只存了页码:通过目录能快速找到某个主 ...

最新文章

  1. 【Linux】一步一步学Linux——watch命令(135)
  2. php生成标准excel表格,php导出生成excel表格几种方法介绍
  3. php自动按天清空库存,swoole+PHP实现自动取消订单,还原库存等操作
  4. 用Docker容器自带的tensorflow serving部署模型对外服务(成功率100%)
  5. Learning 3D Shape Completion from Laser Scan Data with Weak Supervision
  6. 蓝桥杯十六进制转化为十进制
  7. 第三次PR培训(添加常用效果和转场)
  8. php实现过滤中英文标点符号[gbk编码环境]
  9. 用python写网络爬虫-英文翻译
  10. android读取存储mysql图片,Android从Sqlite数据库保存并获取图像
  11. python 常用股票走势图绘制
  12. oracle 数据库回收站,Oracle数据库的回收站
  13. Typora基本使用Markdown基本语法:精炼且详细
  14. Office---Excel操作技巧使用正则表达式
  15. 实施化化工厂人员定位系统势在必行,你不知道的化化工厂人员定位
  16. 360网站卫士常用前端公共库CDN服务
  17. 6代u笔记本完美支持win7_华硕飞行堡垒六代笔记本安装win7系统的操作教程
  18. 用matlab验证傅里叶变换的基本性质
  19. 智能车摄像头动态打角算法
  20. 容水度、持水度、给水度

热门文章

  1. 数据结构之图:加权无向图与寻找最小生成树,Python——27
  2. linux 安装mysql5.7.12_Linux系统上安装mysql5.7.12
  3. 税收分类编码2020_增值税开票系统你会吗?2020最新开票(金税盘版)图文教程详细版...
  4. python网络爬虫系列(七)——selenium的介绍 selenium定位获取标签对象并提取数据 selenium的其它使用方法
  5. LeetCode 2001. 可互换矩形的组数
  6. LeetCode MySQL 1454. 活跃用户(连续dense_rank排名函数)
  7. LeetCode 361. 轰炸敌人(前缀和DP)
  8. LeetCode 616. 给字符串添加加粗标签(Trie树)
  9. [编程启蒙游戏] 1. 猜数字
  10. 程序员面试金典 - 面试题 01.08. 零矩阵