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:
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.
unlike DependencyProperty
which uses Register
, AttachedProperty
uses RegisterAttached
method which tells the Dependency System that other DependencyObject
s can have this property but still the actual static property is stored in DependencyObject
which has the AttachedProperty
.
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.
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).