依赖属性背后的框架机制是什么? [英] What's the framework mechanism behind dependency properties?

查看:52
本文介绍了依赖属性背后的框架机制是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在几本书中阅读了有关依赖项属性的信息,但是它们都有一个共同点,它们只是告诉我们它们是如何实现的(使用 static readonly DependencyProperty 等),但并没有确切说明他们从内部工作的方式.

I have been reading about dependency properties in several books but all have one thing in common, they just tell us how they are implemented( using static readonly DependencyProperty etc.) but does not tell the exact way they work from inside.

我的意思是它们被实现为静态的,但仍然适用于所有对象.
第二点困惑是附加属性.

I mean they are implemented as static but still applies to all objects.
Second point of confusion is attached properties.

有没有可用的教程可以轻松地解释所有这些概念?

Is there any tutorial available that can explain all these concepts in an easy way?

推荐答案

我关于依赖属性工作方式的思维模型:

My mental model of how dependency properties work:

任何 DependencyObject 类都实现两个特殊的属性.一个是类的静态属性,是 DependencyProperty 对象的字典.该类的每个实例都可以在该词典中查找有关每个 DependencyProperty 的元信息-属性的名称,类型,获取和设置时必须调用的任何回调,其如何参与属性继承, 等等.注册依赖项属性时,就是在此字典中添加一个条目.

Any DependencyObject class implements two special properties. One, a static property of the class, is a dictionary of DependencyProperty objects. Every instance of the class can look inside that dictionary to find metainformation about each DependencyProperty - the property's name, its type, any callbacks that have to be called when it's get and set, how it participates in property inheritance, and so on. When you register a dependency property, you're adding an entry to this dictionary.

另一个属性是一个实例属性:这是一个字典,由 DependencyProperty 键控,如果每个 DependencyProperty 都包含本地 value ,已经设置好了.

The other property is an instance property: it's a dictionary, keyed by DependencyProperty, that contains the local value of each DependencyProperty, if it has been set.

您在CLR属性的setter和getter中实现的 SetValue GetValue 方法基本上是对类固醇的惰性评估.他们没有在后备字段中存储和检索属性的值,而是在值字典中存储和检索属性的值.

The SetValue and GetValue methods that you implement in the setter and getter of the CLR property are basically lazy evaluation on steroids. Instead of storing and retrieving the value of the property in a backing field, they store and retrieve the value of the property in the value dictionary.

依赖属性的神奇之处在于 GetValue SetValue 的实际作用.

The magic of dependency properties is in what GetValue and SetValue actually do.

GetValue 在对象的值字典中查找属性的值.如果找不到,它将在父元素上调用 GetValue ,以获取父元素认为的值.例如,当您在 Window 中创建 TextBox 时,查看 TextBox FontFamily 的所有内容都是实际调用 GetValue .除非您明确设置字体,否则在其字典中就不会有该属性的条目.因此, GetValue 要求父元素提供该值.父元素可以设置也可以不设置 FontFamily ;如果不是,则对 GetValue 进行 its 调用,以从 its 父级返回值.依此类推,直到到达 Window 对象并找到实际的 FontFamily 值.

GetValue looks up the value for the property in the object's value dictionary. If it doesn't find it, it calls GetValue on the parent element, to get what the parent element thinks the value is. For instance, when you create a TextBox in a Window, anything that looks at the TextBox's FontFamily is actually calling GetValue. Unless you've explicitly set the font, there's no entry in its dictionary for that property. So GetValue asks the parent element for the value. The parent element may or may not have FontFamily set; if not, its call to GetValue to returns the value from its parent. And so on, until the Window object is reached and the actual FontFamily value is found.

如果在 TextBox 上设置了 FontFamily ,则 SetValue 会将值存储在值字典中.下次需要为该 TextBox 获取 FontFamily 的值时, GetValue 在字典中找到该值并返回它,因此它不需要询问父元素.

If you set FontFamily on the TextBox, SetValue stores the value in the value dictionary. The next time anything needs to get the value of the FontFamily for that TextBox, GetValue finds the value in the dictionary and returns it, so it doesn't need to ask the parent element.

如果在 Window 上设置 FontFamily ,则 SetValue 不仅会更新 Window 的值字典,它会触发一个属性更改事件,所有依赖于该属性的事件都会听到该事件.(记住,这就是为什么它们被称为依赖属性的原因.)如果依赖于该属性的事物本身是依赖属性,则它会触发自己的属性更改事件.就是这样,更改 Window 上的 FontFamily 会更改窗口中每个控件的字体,并提示WPF重新呈现已更改的控件./p>

附加属性使用相同的方法工作.任何可以具有附加属性的对象都有一个字典,用于存储附加属性的值.在XAML中的 CheckBox 上设置 Grid.Column 时,您只是在该 CheckBox 的字典中添加一个条目.当 Grid 需要知道 CheckBox 所在的列时,它将从该字典中查找值.当您在对象上将 Grid.IsSharedSizeScope 设置为 True 时,该对象的字典将包含一个新属性-字典,其中每个 SharedSizeKey

If you set FontFamily on the Window, SetValue not only updates the value in Window's value dictionary, it fires off a property-change event that everything dependent on the property hears. (That's why they're called dependency properties, remember.) And if the thing depending on the property is itself a dependency property, it fires off its own property-change events. This is how it is that changing the FontFamily on the Window changes the font for every control in the window and also prompts WPF to re-render the controls that have changed.

都包含宽度/高度代码>.

Attached properties work using the same kind of approach. Any object that can have attached properties has a dictionary that the attached properties' values are stored in. When you set Grid.Column on a CheckBox in XAML, you're just adding an entry to that CheckBox's dictionary. When the Grid needs to know what column the CheckBox is in, it looks the value up from that dictionary. When you set Grid.IsSharedSizeScope to True on an object, that object's dictionary will contain a new property - a dictionary that contains widths/heights for each SharedSizeKey.

我应该强调,这是我的心理模型.我没有坐在Reflector上,而是研究了 Register GetValue SetValue actual 实现.弄清楚它们是如何工作的.我可能在细节上是错的.但这是一个可以准确预测这些东西的行为的模型,所以它足够好.

I should emphasize that this is my mental model. I haven't sat down with Reflector and looked at the actual implementation of Register, GetValue, and SetValue to figure out how they actually work. I may be wrong about the details. But it's a model that accurately predicts how this stuff behaves, so it's good enough.

在字典中存储属性值的概念对于C#程序员来说很奇怪.不过,这对Python程序员来说是一顶老帽子.在Python中,所有类属性(实际上是所有对象)都存储在词典中,因此您可以通过属性访问器或通过查找它们来获取它们的值.依赖属性和附加属性只是.NET窃取Java值得窃取的所有内容而如今掠夺Python的另一种方式.(或者从Python掠夺的任何地方.)学习Python使我成为了一个更好的C#程序员.我向尚未使用它的任何C#开发人员推荐它.

The concept of storing property values in dictionaries is pretty weird to C# programmers. It's old hat to Python programmers, though. In Python, all class properties - all objects, in fact - are stored in dictionaries, and so you can get to their value either through property accessors or just by looking them up. Dependency properties and attached properties are just another way in which .NET, having stolen everything Java had that was worth stealing, is now plundering Python. (Or from wherever Python plundered them from.) Learning Python has made me a much better C# programmer; I recommend it to any C# developer who hasn't done it yet.

这篇关于依赖属性背后的框架机制是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆