WPF依赖属性学习
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
概述WPF 依赖属性(Dependency Property)是 WPF 框架的核心基础设施之一,它扩展了传统 .NET 属性的能力,为 WPF 提供数据绑定、动画、样式、继承值、属性值变更通知等高级功能。 为什么需要设计依赖属性? 因为依赖属性做到了CLR属性没做到的一些事情。 列举几个场景: 1、数据驱动 UI 的动态性需要“可计算的值 在 WPF 里,绑定的值、样式 Setter 的值、触发器的值、动画帧的值,都是事后才知道的,甚至可以在运行时不断切换来源。 CLR 属性:值写死在一个私有字段里,谁最后 set 就留谁。 依赖属性:属性系统先查看“当前这一帧到底是谁最有发言权”,再给出最终值——也就是“值是从外部来的,我只是按优先级算一算”的依赖计算。 2、大规模对象树的内存压力要求“默认值共享 WPF 的控件树随随便便成千上万实例,如果每个 Button 都把 FontSize = 11 存一份 double,内存就爆炸了。 依赖属性把“默认值”压缩到一个静态全局哈希表里,没显式设置的实例,直接查表用同一份值。 3、样式 / 动画 / 绑定 / 继承 / 触发器 / 资源多路输入需要统一的“优先级规则 同一个 Background,可以是:本地值(红),主题样式(蓝),动画(绿),触发器(黄)…… 传统属性里谁最后 set 谁赢,根本无法表达这种“多源头分时复用”的复杂策略。 4、跨父子树的“属性值继承 典型例子:FontSize 设到 Window 上,所有子孙 TextBlock 直接复用该值,但中途随时可以用样式或本地值覆盖。 传统字段存储实现:父级改一次就要递归遍历整棵树; 依赖属性:子元素在取值时惰性向上询问,逻辑/性能都优雅。 学习依赖属性在创建自定义的时候,创建一个依赖属性的示例如下所示:
首先来看看命名,一个CLR属性是Value,依赖属性是ValueProperty,这是一种命名约定,可以很容易将这两个东西关联起来。 依赖属性都是通过
OnValueChanged是变更回调:
作用:值真正改变后通知控件更新 UI。 e 中包含旧值 e.OldValue 与新值 e.NewValue,可进一步比较差异。 生命周期小结(一个赋值的全过程) 代码 / 绑定 / 动画尝试改变 Value。 WPF 调用 CoerceValue 让控件有机会矫正值。 如果矫正后的值与当前存储值相同,流程结束;否则进入下一步。 触发 OnValueChanged → 更新UI。 因为是 BindsTwoWayByDefault,若存在绑定的源(ViewModel),其对应属性也会被同步。 现在大概了解了依赖属性的设计,你可能也听说过“附加属性”与“继承属性”。 其实官方并没有“继承属性”这个称谓,继承属性只是将依赖属性设置成可继承罢了。 要想更好地理解依赖属性的概念,一个很好的方式就是去看WPF的源码,看看在源码中是如何使用的,现在就让我们一起去源码中找找看吧!! 先来看看普通的依赖属性定义: 目前我们接触到了
这里官方源码将按钮是否按下这个属性设置为了只读依赖属性,为什么官方是这样做的呢? 想象一下一个按钮的 如果你把它做成一个普通的可以随意读写的属性:
那么任何代码都可以修改它,这会破坏按钮的内在逻辑和行为一致性。 如果你把它做成一个普通的只读属性:
虽然外部代码不能修改了,但这样做有几个缺点: 不支持 WPF 高级功能:它不再是一个依赖属性,因此无法享受数据绑定、样式、动画、属性值继承等 WPF 的核心特性。比如,你无法在 XAML 中写一个 Trigger 来在 IsPressed 为 true 时改变按钮的背景色。 缺少变更通知:如果 _isPressed 的值改变了,WPF 的其他部分(比如 UI 渲染系统)不会自动知道。你需要手动实现 INotifyPropertyChanged 接口,这额外增加了复杂性。 为了解决上述问题,WPF 引入了“只读依赖属性” (Read-Only Dependency Property) 。这种属性拥有两全其美的优势: 对外是只读的:保护了属性的完整性,防止外部代码随意篡改。 内部是可读写的:属性的“所有者”可以在特定逻辑下修改其值。 拥有依赖属性的全部特性:支持数据绑定、样式、动画、触发器等。 再来看看附加依赖属性: Grid.Row是一个很经典的附加依赖属性。 注册附加依赖属性使用的是 附加属性必须提供静态的 在WPF中一个很经典的可继承依赖属性的例子就是 使用了 这个枚举类有以下几个选项:
现在只是差不多了解了WPF中的依赖属性的一些概念与使用,要想真正明白依赖属性的设计与实现,还得多研究研究源码。 转自https://www.cnblogs.com/mingupupu/p/19074134 该文章在 2025/9/5 8:49:29 编辑过 |
关键字查询
相关文章
正在查询... |