Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between Attached and non-Attached Dependency Properties in Silverlight

Okay Stackers, I've spent a good couple of hours on this question, and I want to know if anybody has a definitive answer.
For all the research I've done, I can't find ANY difference between .Register and .RegisterAttached in Silverlight. Now, before you jump the gun and tell me that .RegisterAttached is used for attaching a DP to another class, try implementing an Attached Dependency Property using DependencyProperty.Register(). I have found not a single difference, and so I am at a loss as to what the difference is.
Furthermore, in my specific case, I'm attempting to extend the functionality of the Grid class, and want to give it some extra properties. As such, I've tried listing passing both typeof(Grid) and typeof(FluidLayoutManager) (the implementing class) as the ownerType parameter and it also seems to make very little difference... (I believe it does make a difference when I pass two custom classes from the same namespace. However when passing a Microsoft defined class vs. a custom class, I always have it showing up in the XAML as a DP of the custom class.)
Any clarification on this topic would be much appreciated, as I'm sitting here scratching my head, and wondering if there is any difference at all, or if Microsoft is just screwing with me once again.

like image 351
Melodatron Avatar asked Jul 27 '11 11:07

Melodatron


People also ask

What is attached dependency property?

An attached property is a Extensible Application Markup Language (XAML) concept. Attached properties enable extra property/value pairs to be set on any XAML element that derives from DependencyObject, even though the element doesn't define those extra properties in its object model.

What is an attached property?

Attached property is property that has been seized pursuant to a court order, either as a provisional pre-judgment remedy or for the enforcement of a final judgment. Property may be attached only after the commencement of a lawsuit.


2 Answers

It is wrong to believe that "RegisterAttached allows the value to be assigned to any dependency object whereas Register only allows it to be attached to the class passed as the ownerType parameter". Here is a perfectly working example of an attached property registered with Register:

class FooPropertyDeclaringType
{
    public static readonly DependencyProperty FooProperty = 
        DependencyProperty.Register("Foo", typeof(int), typeof(FooPropertyDeclaringType));
}

class SomeUnrelatedType : DependencyObject { }

class Program
{
    static void Main()
    {
        var obj = new SomeUnrelatedType();
        obj.SetValue(FooPropertyDeclaringType.FooProperty, 10);
        Debug.Assert(10 == (int)obj.GetValue(FooPropertyDeclaringType.FooProperty));
    }
}

Reflector shows that the only difference between Register and RegisterAttached is that the Register throws out much of the supplied metadata and only preserves it for the instances of registering class (via OverrideMetadata). It means that attributes such as Inherits and various update notifications usually specified in the metadata do not work on properties registered with Register and attached to objects of other types (other than the registering type). So Register is actually a stripped down version of RegisterAttached. It was probably made this way for performance reasons.

In the example linked by Haris Hasan in the comments to his answer, if you change RegisterAttached to Register, the buttons stop moving (because the property no longer provides AffectsParentArrange metadata for Button type) but they are nevertheless redrawn in their new locations when you resize the window. But if you add the same metadata to the Button type after a call to InitializeComponent():

RadialPanel.AngleProperty.OverrideMetadata(
    typeof(Button), 
    new FrameworkPropertyMetadata(
        0.0, FrameworkPropertyMetadataOptions.AffectsParentArrange));

then everything works again as if RegisterAttached was called.

like image 130
srgstm Avatar answered Sep 30 '22 17:09

srgstm


Given the discussions flowing in comments I will try to do this one in plain English:

The main difference between Attached Dependency Properties and Dependency Properties (and therefore between .Register and .RegisterAttached) is that RegisterAttached allows the value to be assigned to any dependency object whereas Register only allows it to be attached to the class passed as the ownerType parameter.

As Haris Hasan mentions (deep in the comment thread), your example is using the only type allowed (i.e. CustomControl) and does not show you that the Attached version can be assigned to ANY dependency object.

e.g. you can do this with your Attached Dependency Property (but not a plain DP):

<Grid local:AttacherClass.ADP1="1" x:Name="LayoutRoot" Background="White">
</Grid>

The best reference for ADPs I can find is this one: http://msdn.microsoft.com/en-us/library/ms749011.aspx

We used ADPs as the basis of a localisation system, so that translations could be parasited onto objects during load rather than using horrendously long bindings. Couldn't do that with DPs

Update:

I would also like to clarify that the parent limitation applies to XAML based use of the attribute. From code the parent limitation apparently does not apply.

like image 34
Gone Coding Avatar answered Sep 30 '22 16:09

Gone Coding