Question

(I am totally new to this concept so I may be asking very basic questions.)

A dependency property is registered with the code below:

public static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata);

Logically, it did nothing but associate a property name with the owner type.

So if I have multiple instances of the owner type, and each instance set the DP to different values.

How could these values be stored?

Update 1 - 10:04 AM 10/30/2013

I read about the Attached Property from here: http://wpftutorial.net/DependencyProperties.html

Attached Properties

Attached properties are a special kind of DependencyProperties. They allow you to attach a value to an object that does not know anything about this value.

A good example for this concept are layout panels. Each layout panel needs different data to align its child elements. The Canvas needs Top and Left, The DockPanel needs Dock, etc. Since you can write your own layout panel, the list is infinite. So you see, it's not possible to have all those properties on all WPF controls.

The solution are attached properties. They are defined by the control that needs the data from another control in a specific context. For example an element that is aligned by a parent layout panel.

So in the following code snippet:

<Canvas>
    <Button Canvas.Top="20" Canvas.Left="20" Content="Click me!"/>
    <Button Canvas.Top="40" Canvas.Left="20" Content="Click me!"/>
</Canvas>

Apparently we cannot give all the align properties such as Top, Left to Button. So Canvas defines such properties and they are "attached" to Button control.

When Canvas.Top is specified as an "attribute" of the Button in XAML, it will invoke the SetTop() method which is defined in the Canvas type. And the Button is passed in as the element argument. I think that's how Canvas knows which Button use which Top value.

public static void SetTop(UIElement element, double length);

But I don't see why the Attached Property has to be a Dependency Property? What's the connection between them?

Thanks!

Was it helpful?

Solution

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

OTHER TIPS

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. :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top