【发布时间】:2011-01-31 02:31:41
【问题描述】:
我试图弄清楚依赖属性到底是什么,但是当我在任何地方寻找定义时,我只找到“如何使用”而不是“它是什么”。 想象一下你在面试中被问到 - 什么是依赖属性。你的答案是什么?
【问题讨论】:
标签: c# wpf dependency-properties
我试图弄清楚依赖属性到底是什么,但是当我在任何地方寻找定义时,我只找到“如何使用”而不是“它是什么”。 想象一下你在面试中被问到 - 什么是依赖属性。你的答案是什么?
【问题讨论】:
标签: c# wpf dependency-properties
“为您提供了一堆基础架构,可以完成您通常想要对普通属性执行的所有操作 - 验证它、将其强制到适当的范围内、发出更改通知以及许多其他方面。”
【讨论】:
依赖属性是由 WPF 属性系统支持的属性,而不是由声明类中的字段支持的属性。
这样做的意义在于,由于 WPF 拥有该属性,因此 WPF 在计算属性值时可以考虑各种因素——例如动画、样式和数据绑定。另一个结果是,由于属性由 WPF 管理,因此不必在概念上具有状态的类上声明它们:因此,附加属性允许例如将 Grid 特定状态与非 Grid 对象相关联的 Grid。
(顺便说一下,我在上面提到了 WPF,因为这是使用 DP 的主要框架,但 Windows Workflow Foundation 也有依赖属性的概念。所以严格来说,DP 是一个由一个外部属性系统,特别是在获取属性值时允许“最后设定值”以外的因素发挥作用的系统。)
【讨论】:
DependencyProperty 是一种属性,其值取决于(或可以取决于)某些其他来源(例如动画、数据绑定、样式或可视树继承)。常规属性的值存储在它所属的对象中,而您可以将依赖属性视为存储在某处的数据库中。该数据库本质上由一个字典组成,该字典将 (object, property) 对映射到它们的值,以及哪些属性依赖于其他属性的映射(例如,当您更改面板的 DataContext 时,它可以通知面板内的所有孩子)。
那么为什么他们将属性值存储在某个神奇的数据库中呢?有几个原因:
它减少了存储空间。向一个类添加一个属性(即使它的值为空)会为该类的每个实例添加 4 个字节(对于 64 位进程为 8 个)空间。 DependencyProperty 仅在实例具有值时才占用空间。例如,一个 FrameworkElement 有几十个依赖属性,其中大部分从未赋值。如果所有这些属性都存储在类中,则每个实例将有数百个字节。相反,每个实例只有大约 40 个字节。
它启用附加属性。像Canvas.Left 和Grid.Row 这样的属性必须存储在从未听说过Canvas 或Grid 的对象上,那么你把它们放在哪里呢?您将它们放在某个数据库中。
它启用自动属性更改。想象一下您将如何实现样式或属性继承(在父元素上设置字体或数据上下文之类的东西并将其值传播到所有子元素的能力)。将所有这些都存储在数据库中,因此代码都在一个地方,而不是为需要它的每个对象和属性单独实现。
【讨论】:
OnPaint,所以如果任何事情变得太复杂,你总是可以退回到那个。如果需要显示文本,只需从 OnPaint 中绘制即可。 WPF 没有 OnPaint,因此您可能需要能够为每个字形使用不同的对象来表示文本。
一个依赖属性依赖于多个提供者来确定它在任何时间点的值。这些提供者可以是一个不断改变其值的动画,一个其属性值向下传播到其子级的父元素,等等。
可以说,依赖属性的最大特点是它内置的提供更改通知的能力。
每当依赖属性的值发生变化时,WPF 都可以根据属性的元数据自动触发一些操作。这些动作可以重新渲染—— 设置适当的元素,更新当前布局,刷新数据绑定,以及 多得多。此内置更改通知启用的最有趣的功能之一- 化是属性触发器,它使您能够执行自己的自定义操作,当 属性值变化,无需编写任何程序代码
【讨论】: