今天我们说说依赖属性

什么是依赖属性?

当然,学术定义依旧Please Baidu:https://baike.baidu.com/item/%E4%BE%9D%E8%B5%96%E5%B1%9E%E6%80%A7/637278?fr=aladdin

那么,请问你看明白了吗?明白了就请出门左转吧,同时本人也是很佩服的,本人也是经人点拨后才了解依赖属性到底是个什么东西,他真实的定义就是:

依赖属性——一个反抗旧思想旧家庭的新时代抗争青年(说白了就是个愤青)

先讲一个故事:

贾少爷,姓贾名五代,出身贵族家庭,其父贾老爷,姓贾名四代,著名商旅,其祖父贾爷爷,姓贾名三代,文人墨客,其高祖贾高祖,姓贾名二代,官宦重臣,其先祖贾剑客,姓贾名一代,侠士风流,家中历代均有家产流传给后世。流传图谱如下:

贾一代:隐士剑谱

贾二代:丞相司印

贾三代:风雅画卷

贾四代:金银重鼎

以上四件神器流传至今,均传给了贾五代

结果贾五代是个家族异类,专心研究佛法,手里最看重的宝贝是:念珠木鱼。

这就尴尬了,作为贾少爷,只想研究佛法,那四件价值连城的宝贝根本瞧不上(给我呀……),一心想要和家庭抗争,只想拿着念珠木鱼烧香拜佛,所以这事该怎么办?

好的故事到此结束。

其实这就是依赖属性,每个父类都有其自有属性,当一个子类多级继承其父类时,那么它必然继承了其父类的所有可以继承的成员,所以就会造成最后的一个叶子子类臃肿不堪,本来不想要的属性也因为继承链而被传递给子类。上面的故事用代码解释就是这样的。

  1. public class JiaYidai
  2. {
  3. public string YinShiJianPu { get; set; }
  4. }
  5.  
  6. public class JiaErdai:JiaYidai
  7. {
  8. public string ChengXiangSiYin { get; set; }
  9. }
  10.  
  11. public class JiaSandai : JiaErdai
  12. {
  13. public string FengYaHuaJuan { get; set; }
  14. }
  15.  
  16. public class JiaSidai : JiaSandai
  17. {
  18. public string JinYinZhongDing { get; set; }
  19. }
  20.  
  21. public class JiaWudai : JiaSidai
  22. {
  23. public string NianZhuMuYu { get; set; }
  24. }

那么当我们在调用JiaWudai时肯定会出现之前的父类的属性,如图:

那么那些不相干的属性就会同步继承而来,所以依赖属性就是为了解决这个问题而产生的。

我们来看如何来解决这个问题,既然贾五代不想继承其它的属性,那么我们就将其父类的宝贝都做成依赖属性,看看会怎么样。

首先我们先建立一个依赖属性对象:

  1. public class DependencyProperty
  2. {
  3. /// <summary>
  4. /// 属性名
  5. /// </summary>
  6. internal string Name;
  7. /// <summary>
  8. /// 属性值
  9. /// </summary>
  10. internal object Value;
  11.  
  12. /// <summary>
  13. /// 构造函数
  14. /// </summary>
  15. /// <param name="name"></param>
  16. /// <param name="propertyName"></param>
  17. /// <param name="ownerType"></param>
  18. /// <param name="defaultValue"></param>
  19. private DependencyProperty(string name, Type propertyName, Type ownerType, object defaultValue)
  20. {
  21. this.Name = name;
  22. this.Value = defaultValue;
  23. }
  24. /// <summary>
  25. /// 创建属性的方法
  26. /// </summary>
  27. /// <param name="name"></param>
  28. /// <param name="propertyName"></param>
  29. /// <param name="ownerType"></param>
  30. /// <param name="defaultValue"></param>
  31. /// <returns></returns>
  32. public static DependencyProperty CreateInstance(string name, Type propertyName, Type ownerType, object defaultValue)
  33. {
  34. DependencyProperty dp = new DependencyProperty(name, propertyName, ownerType, defaultValue);
  35. return dp;
  36. }
  37. }

之后我们再建立贾五代的四个父级类,代码如下

  1. public class JiaYidai
  2. {
  3. public static readonly DependencyProperty InstantYidai = DependencyProperty.CreateInstance("YinShiJianPu", typeof(string), typeof(JiaYidai), "隐士剑谱");
  4. public object GetValueYidai(DependencyProperty dp)
  5. {
  6. return dp.Value;
  7. }
  8. public void SetValueYidai(DependencyProperty dp, string value)
  9. {
  10. dp.Value = value;
  11. }
  12. public string YinShiJianPu
  13. {
  14. get
  15. {
  16. return GetValueYidai(InstantYidai).ToString();
  17. }
  18. set
  19. {
  20. SetValueYidai(InstantYidai, value);
  21. }
  22. }
  23. }
  24.  
  25. public class JiaErdai : JiaYidai
  26. {
  27.  
  28. public static readonly DependencyProperty InstantErdai = DependencyProperty.CreateInstance("ChengXiangSiYin", typeof(string), typeof(JiaYidai), "丞相司印");
  29. public object GetValueErdai(DependencyProperty dp)
  30. {
  31. return dp.Value;
  32. }
  33. public void SetValueErdai(DependencyProperty dp, string value)
  34. {
  35. dp.Value = value;
  36. }
  37. public string ChengXiangSiYin
  38. {
  39. get
  40. {
  41. return GetValueErdai(InstantErdai).ToString();
  42. }
  43. set
  44. {
  45. SetValueErdai(InstantErdai, value);
  46. }
  47. }
  48. }
  49.  
  50. public class JiaSandai : JiaErdai
  51. {
  52. public static readonly DependencyProperty InstantSandai = DependencyProperty.CreateInstance("FengYaHuaJuan", typeof(string), typeof(JiaYidai), "风雅画卷");
  53. public object GetValueSandai(DependencyProperty dp)
  54. {
  55. return dp.Value;
  56. }
  57. public void SetValueSandai(DependencyProperty dp, string value)
  58. {
  59. dp.Value = value;
  60. }
  61. public string FengYaHuaJuan
  62. {
  63. get
  64. {
  65. return GetValueSandai(InstantSandai).ToString();
  66. }
  67. set
  68. {
  69. SetValueSandai(InstantSandai, value);
  70. }
  71. }
  72. }
  73.  
  74. public class JiaSidai : JiaSandai
  75. {
  76. public static readonly DependencyProperty InstantSidai = DependencyProperty.CreateInstance("JinYinZhongDing", typeof(string), typeof(JiaYidai), "金银重鼎");
  77. public object GetValueSidai(DependencyProperty dp)
  78. {
  79. return dp.Value;
  80. }
  81. public void SetValueSidai(DependencyProperty dp, string value)
  82. {
  83. dp.Value = value;
  84. }
  85. public string JinYinZhongDing
  86. {
  87. get
  88. {
  89. return GetValueErdai(InstantErdai).ToString();
  90. }
  91. set
  92. {
  93. SetValueErdai(InstantErdai, value);
  94. }
  95. }
  96. }

然后我们再次调用

咦,为什么没有变化呢?查看源代码就会发现我们为了调用的方便,我们在依赖属性的SetValue和GetValue方法后封装了一个public的同名属性,这个属性是可以继承的,所以贾五代依旧可以看到并使用这些属性。可以通过删除父级类中的属性进行测试,在从不再详述。当然如果真的希望各个属性间不发生任何属性继承,可以取消所有继承,让各级父类分别继承这五个依赖属性,就可以实现类构成的精简

那么这个依赖属性有什么用?让我们看另外一个例子,代码如下:

  1. public class JiaYidai
  2. {
  3. private static DependencyProperty Instant = DependencyProperty.CreateInstance("YinShiJianPu", typeof(string), typeof(JiaYidai), "隐士剑谱");
  4. public object GetValueYidai(DependencyProperty dp)
  5. {
  6. return dp.Value;
  7. }
  8. public void SetValueYidai(DependencyProperty dp, string value)
  9. {
  10. dp.Value = value;
  11. }
  12. public string YinShiJianPu
  13. {
  14. get
  15. {
  16. return GetValueYidai(Instant).ToString();
  17. }
  18. set
  19. {
  20. SetValueYidai(Instant, value);
  21. }
  22. }
  23. }
  24.  
  25. public class JiaErdai : JiaYidai
  26. {
  27.  
  28. private static DependencyProperty Instant = DependencyProperty.CreateInstance("ChengXiangSiYin", typeof(string), typeof(JiaYidai), "丞相司印");
  29. public object GetValueErdai(DependencyProperty dp)
  30. {
  31. return dp.Value;
  32. }
  33. public void SetValueErdai(DependencyProperty dp, string value)
  34. {
  35. dp.Value = value;
  36. }
  37. public string ChengXiangSiYin
  38. {
  39. get
  40. {
  41. return GetValueErdai(Instant).ToString();
  42. }
  43. set
  44. {
  45. SetValueErdai(Instant, value);
  46. }
  47. }
  48. }
  49.  
  50. public class JiaSandai : JiaErdai
  51. {
  52. private static DependencyProperty Instant = DependencyProperty.CreateInstance("FengYaHuaJuan", typeof(string), typeof(JiaYidai), "风雅画卷");
  53. public object GetValueSandai(DependencyProperty dp)
  54. {
  55. return dp.Value;
  56. }
  57. public void SetValueSandai(DependencyProperty dp, string value)
  58. {
  59. dp.Value = value;
  60. }
  61. public string FengYaHuaJuan
  62. {
  63. get
  64. {
  65. return GetValueSandai(Instant).ToString();
  66. }
  67. set
  68. {
  69. SetValueSandai(Instant, value);
  70. }
  71. }
  72. }
  73.  
  74. public class JiaSidai : JiaSandai
  75. {
  76. private static DependencyProperty Instant = DependencyProperty.CreateInstance("JinYinZhongDing", typeof(string), typeof(JiaYidai), "金银重鼎");
  77. public object GetValueSidai(DependencyProperty dp)
  78. {
  79. return dp.Value;
  80. }
  81. public void SetValueSidai(DependencyProperty dp, string value)
  82. {
  83. dp.Value = value;
  84. }
  85. public string JinYinZhongDing
  86. {
  87. get
  88. {
  89. return GetValueErdai(Instant).ToString();
  90. }
  91. set
  92. {
  93. SetValueErdai(Instant, value);
  94. }
  95. }
  96. }
  97.  
  98. public class JiaWudai : JiaSidai
  99. {
  100. public string NianZhuMuYu { get; set; }
  101. }

再运行如图所示代码:

看结果:

咦,本来改的是子类,怎么把父类给改了?没错这就是依赖属性的好处,一处修改,大家都知道了,想想也知道,假如贾五代这天闲来无事,打开了风雅画卷,突然无聊,拿起笔来在画卷上写了个hello world,然后把画卷收回去了,他的祖父贾三代再拿出来打开的时候hello world会没了么?写上了不擦肯定不会消失的,这就是依赖属性的好处。

所以如果依赖属性和使用了依赖属性的对象再继承一个接口INotifyPropertyChanged的话,好像……诞生了一个新的世界,这个世界让我们下回分解……

WPF入门(2)——依赖属性的更多相关文章

  1. WPF 精修篇 依赖属性

    原文:WPF 精修篇 依赖属性 依赖属性使用场景 1. 希望可在样式中设置属性. 2. 希望属性支持数据绑定. 3. 希望可使用动态资源引用设置属性. 4. 希望从元素树中的父元素自动继承属性值. 5 ...

  2. WPF中的依赖属性

    1. WPF中的依赖属性 依赖属性是专门基于WPF创建的.在WPF库实现中,依赖属性使用普通的C#属性进行了包装,使用方法与普通的属性是相同的. 1.1 依赖属性提供的属性功能 资源 数据绑定 样式 ...

  3. WPF学习笔记——依赖属性(Dependency Property)

    1.什么是依赖属性 依赖属性是一种可以自己没有值,并且通过Binding从数据源获得值(依赖在别人身上)的属性,拥有依赖属性的对象被称为"依赖对象". 依赖项属性通过调用 Regi ...

  4. WPF教程:依赖属性

    一.什么是依赖属性 依赖属性就是一种自己可以没有值,并且可以通过绑定从其他数据源获取值.依赖属性可支持WPF中的样式设置.数据绑定.继承.动画及默认值. 将所有的属性都设置为依赖属性并不总是正确的解决 ...

  5. [No000012D]WPF(5/7)依赖属性

    介绍 WPF带来了很多传统 Windows 应用程序没有的新特性和选择.我们已经讨论了一些 WPF 的特性,是时候更进一步介绍其他特性了.当你读完这个系列之前的文章,我希望你已经或多或少地了解了 WP ...

  6. (原创)2. WPF中的依赖属性之二

    1 依赖属性 1.1 依赖属性最终值的选用 WPF属性系统对依赖属性操作的基本步骤如下: 第一,确定Base Value,对同一个属性的赋值可能发生在很多地方.还用Button的宽度来进行举例,可能在 ...

  7. 【转】【WPF】关于依赖属性的ValidateValueCallback,PropertyChangedCallback和CoerceValueCallback的执行顺序

    三个回调对应依赖属性的验证过程,改变过程和强制转换过程. class Dobj : DependencyObject { //依赖属性包装 public int MyProperty { get { ...

  8. WPF usercontrol 自定义依赖属性

    1.依赖属性不同意一般属性,一般属性主要定义在对象中,而依赖属性是存在一个特殊的依赖属性表中.2.当我们触发改变值时,需要通过SetValue这种方式进行触发. UserControl1.xaml: ...

  9. WPF 主动触发依赖属性的 PropertyChanged

    需求背景 需要显示 ViewModel 中的 Message/DpMessage,显示内容根据其某些属性来确定.代码结构抽象如下: // Model public class Message : IN ...

  10. WPF快速入门系列(2)——深入解析依赖属性

    一.引言 感觉最近都颓废了,好久没有学习写博文了,出于负罪感,今天强烈逼迫自己开始更新WPF系列.尽管最近看到一篇WPF技术是否老矣的文章,但是还是不能阻止我系统学习WPF.今天继续分享WPF中一个最 ...

随机推荐

  1. python 生成随机字符串

    1.生成随机字符串 #数字+字母+符号 def getRandChar(n): l = [] #sample = '0123456789abcdefghijklmnopqrstuvwxyz!@#$%^ ...

  2. JAVA 基础知识。程序运方法。

    dos     常用命令    dir     查看此文件夹目录下的所有程序    cd..    返回上一层目录    盘符:  直接切换至相应的盘符    cd 目录 切换至指定的目录    cd ...

  3. 【解构云原生】初识Kubernetes Service

    编者按:云原生是网易杭州研究院(网易杭研)奉行的核心技术方向之一,开源容器平台Kubernetes作为云原生产业技术标准.云原生生态基石,在设计上不可避免有其复杂性,Kubernetes系列文章基于网 ...

  4. Python Redis常用操作(持续更新)

    目录 1.Redis简介 2.Redis部署 3.Redis API应用 4.String操作 1.Redis简介 redis是业界主流的key-value,nosql数据库之一.和Memcached ...

  5. [JavaWeb基础] 019.Struts2 MVC架构之ModelDriven

    用过struts1的人接触struts2的时候,通常会产生一个疑惑,明明struts1已经把action的form分开了,为什么struts2确把模型放在action中定义.其实这个方式只是想让act ...

  6. Python数据分析:pandas玩转Excel (二)

    1 对Excel文件的操作 方法一: 使用xlrd库或者xlwt库进行对excel表格的操作读与写: 方法二: pandas库同样支持excel的读写操作:且更加简便. 2 pd.read_excel ...

  7. 分别针对Customers表与Order表的通用查询操作

    1.针对customers表通用的查询操作 CustomerForQuery package com.aff.PreparedStatement; import java.lang.reflect.F ...

  8. 利用Python网络爬虫采集天气网的实时信息—BeautifulSoup选择器

    相信小伙伴们都知道今冬以来范围最广.持续时间最长.影响最重的一场低温雨雪冰冻天气过程正在进行中.预计,今天安徽.江苏.浙江.湖北.湖南等地有暴雪,局地大暴雪,新增积雪深度4-8厘米,局地可达10-20 ...

  9. 使用ADMT和PES实现window AD账户跨域迁移-介绍篇

    使用 ADMT 和 pwdmig 实现 window AD 账户跨域迁移系列: 介绍篇 ADMT 安装 PES 的安装 ADMT:迁移组 ADMT:迁移用户 ADMT:计算机迁移 ADMT:报告生成 ...

  10. java方法句柄-----5.Method Handles in Java

    Method Handles in Java 目录 Method Handles in Java 1.介绍 2.什么是MethodHandle 3. Method Handles vs Reflect ...