How Dependency Property tell the object to apply to?

╄→尐↘猪︶ㄣ 提交于 2019-12-04 08:09:22

Usually when we define a DependencyProperty, we also define a CLR 'wrapper' that enables us to use the DependencyProperty in code:

public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register(
    "Items", typeof(ObservableCollection<string>), typeof(MainWindow), 
     new UIPropertyMetadata(new ObservableCollection<string>()));

public ObservableCollection<string> Items
{
    get { return (ObservableCollection<string>)GetValue(ItemsProperty); }
    set { SetValue(ItemsProperty, value); }
}

Here you can see the GetValue and SetValue methods that @Clemens was talking about. We get access to these methods in a Window and/or UserControl because they both extend the DependencyObject class. You can also see that the Items property here is not static... it is just the definition of the DependencyProperty that is static.


UPDATE >>>

There's not really much point in asking why does an Attached Property have to be a DependencyProperty? because in .NET, they just are... they were just designed like that. A better question might be, what benefit does an Attached Property get from being a DependencyProperty?

The answer to that would be the same as if asked what benefit does a property get from being a DependencyProperty? The main benefits being that these properties can be used in Bindings, Styles, Animations and Resources among other things. More details can be found from the (already linked to in the comments) two very important pages on MSDN for any WPF developers:

Dependency Properties Overview

Attached Properties Overview

To answer your question I need to start from the very basics of Dependency system (you already know most of these things below, but I think after reading it your question might answer itself)

DependencyProperty should be defined within a class that is derived from DependencyObject because DependencyObject implements some methods and members (which most of them are private and developers can't see them). These implementations provide the DependencyObject with the abilities to store and retrieve data with static reference to the class (instead of reference to an instance of the class)

The way we store and retrive data is either through the DependencyProperty's wrapper or directly by GetValue and SetValue (which are DependencyObject's methods) or through bindings. Either way the static DependencyProperty is the "key" to find the proper value.

When you register a DependencyProperty, the Dependency system is informed that a new DependencyProperty is added to its resources (something like a list, filled with DependencyProperties that you've registerd). Now if you store something as [this.]SetValue(MyProperty, value), you're essentially updating a resource of object this (which you can imagine as this.Resources[MyProperty]).

This works just like a normal property on the outside, but considering the UIPropertyMetadata and other Dependency stuff, your DependencyProperty is equipped with a handful of unique abilities to Coerce, participate in animations, notify when changed and etc and can do much more than a simple property.

remember extension?

public static void MyExtension(this MyType target, string parameter, ...)
{
    target.MyFunction(parameter, ...);
}
var t = new MyType();
t.MyExtension("test");

AttachedProperty is somehow the combination of DependencyProperty and extension, with some differences:

  1. Wrappers of AttachedProperty are static and take a class reference as input to know where are they attached. The target of a DependencyProperty is usually this (unless you change GetValue and SetValue to something like otherObject.SetValue(MyProperty, value) ). but unlike DependencyProperty, The target of an AttachedProperty (which have to be a DependencyObject itself) is being passed to it as a parameter. and again the reason it has to be a DependencyObject is that only a DependencyObject is capable of having a set of resources to store a DependencyProperty in.

  2. unlike DependencyProperty which uses Register, AttachedProperty uses RegisterAttached method which tells the Dependency System that other DependencyObjects can have this property but still the actual static property is stored in DependencyObject which has the AttachedProperty.

  3. in Extension, this before its first parameter is used to "extend" the type next to it. in AttachedProperty there's no this, in fact it's always the DependencyObject class which is extended.

  4. Unlike AttachedProperty, an extension can't store data by itself unless you write a few lines of code similar to the implementation of the AttachedProperty. e.g. implementing a static list of KeyValuePairs (Value for the actual data and Key for knowing to whom do they belong)


Edit:

After Clemens's comment I need to add that AttachedProperty is not actually an extension. the reason I brought up extension is that by comparing these two, you can see the reason why a normal property can't be attached to a DependencyObject because in order to store data in other objects, some collection like a Resource is needed (which DependencyObject has).

I've always viewed DependencyProperties as a property definition, which is different from a normal property.

The property definition contains the property type, name, default value, etc and includes a pointer showing where to find the property value. But it doesn't contain the value itself.

This allows you to use DependencyProperties in Bindings, since you can set the property up to get its value from a bound expression instead of from the object itself.

This is important for AttachedProperties because their value doesn't reside on the object they are attached to. They need the ability to look up their value in a different location than the object itself, and DependencyProperties allow this.

You can't do this with a regular property because a normal property's value is meant to be found on the object itself, but an AttachedProperty doesn't exist on the object it's attached to.

That's the simple version. :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!