Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Dependency Properties: Why do I need to specify an Owner Type?

This is how I register a DependencyProperty:

    public static readonly DependencyProperty UserProperty = 
        DependencyProperty.Register("User", typeof (User), 
             typeof (NewOnlineUserNotifier));                                                                                                                 


    public User User
    {
        get
        {
            return (User)GetValue(UserProperty);
        }
        set
        {
            SetValue(UserProperty, value);
        }
    }

The third parameter of the DependencyProperty.Register method requires you to specify the type of the Control where the Dependency Property resides in (in this case, my User Control is called NewOnlineUserNotifier).

My question is, why do you actually specify the type of the owner, and what happens if you specify a different type than the actual owner's ?

like image 593
Andreas Grech Avatar asked May 15 '09 13:05

Andreas Grech


2 Answers

The type that you call the Register method from is not the de facto owner of the property, therefore you can't specify a different type than the actual owner since the type you specify is the actual owner.

An example where this may be useful is when you create a custom control that contains other controls. Previously with WinForms if you had some extra information that was only useful to that container, but semantically belonged to the child, then the best you could do was place that information in the hold-all "Tag" property. This both removed type safety and you were never sure that another class wouldn't try and store something else in the tag. Now with WPF dependency properties allow you to tie values to objects without the object itself needing to hold the value. A trivial example:

public class ButtonContainer : Control
{
    public Button ChildButton { get; set; }

    public static readonly DependencyProperty FirstOwnerProperty =
    DependencyProperty.Register("FirstOwner", typeof(ButtonContainer),
         typeof(Button));

    public ButtonContainer()
    {
        ChildButton = new Button();
        ChildButton.SetValue(FirstOwnerProperty, this);
    }

}

Now the button has an extra property that only makes sense within the context of the ButtonContainer and can only be accessed within the context of the ButtonContainer - like a typesafe, encapsulated Tag.

Using the new class as follows:

ButtonContainer container1 = new ButtonContainer();

ButtonContainer container2 = new ButtonContainer();
container2.ChildButton = container1.ChildButton;

As the ChildButton is moved from one container to another the value of its FirstOwnerProperty travels with it as though it was a real member of the Button class. Container2 can call ChildButton.GetValue(FirstOwnerProperty) and find out which ButtonContainer originally created the button (why it might want to do this is left as an exercise for the reader...). All of this is possible without the need to subclass the button to a narrow speciality.

like image 65
Martin Harris Avatar answered Nov 10 '22 09:11

Martin Harris


This is because the same DependencyProperty can be defined differently (with different metadata) for several types

like image 32
Thomas Levesque Avatar answered Nov 10 '22 08:11

Thomas Levesque