WPF依赖属性:为什么需要指定所有者类型?

8
这是我注册一个 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);
        }
    }
DependencyProperty.Register方法的第三个参数要求您指定依赖属性所在的控件类型(在本例中,我的用户控件名为NewOnlineUserNotifier)。
我的问题是,为什么需要指定所有者的类型,如果指定了与实际所有者不同的类型会发生什么?
3个回答

7
您从中调用Register方法的类型并非属性的实际所有者,因此您无法指定与实际所有者不同的类型,因为您指定的类型就是实际所有者。
一个示例场景是当您创建包含其他控件的自定义控件时。以前在WinForms中,如果您有一些仅对该容器有用但语义上属于子级的额外信息,则最好的做法是将该信息放置在“Tag”属性中。这既去除了类型安全性,也无法确保另一个类不会尝试在标记中存储其他内容。现在,使用WPF依赖属性,您可以将值绑定到对象,而无需对象本身持有该值。以下是一个简单的示例:
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);
    }

}

现在这个按钮有一个额外的属性,只在ButtonContainer的上下文中才有意义,也只能在ButtonContainer的上下文中访问 - 就像类型安全、封装的标签。

可以按照以下方式使用新类:

ButtonContainer container1 = new ButtonContainer();

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

当ChildButton从一个容器移动到另一个容器时,它的FirstOwnerProperty值也随之移动,就像它是Button类的一个真正成员一样。Container2可以调用ChildButton.GetValue(FirstOwnerProperty)并找出最初创建按钮的ButtonContainer(为什么要这样做留给读者自己思考...)。所有这些都可以在不需要将按钮子类化为狭窄专业性的情况下实现。

2
我们是否应该使用附加属性而不是具有不同ownerType的普通DependencyProperty? - Lukazoid

3
这是因为同一DependencyProperty可以针对多种类型进行不同的定义(具有不同的元数据)。

3

简而言之,当您注册一个DP时,您将一个对象(DP)添加到附加到类(owner)的列表中。此操作仅在声明它的类中“存在”,并且通常与其无关。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接