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

发布于 2024-07-21 05:04:58 字数 728 浏览 2 评论 0原文

这就是我注册 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)。

我的问题是,为什么您实际上要指定所有者的类型,如果您指定的类型与实际所有者的类型不同,会发生什么?

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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

感情洁癖 2024-07-28 05:04:58

您调用 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 最初创建了该按钮(为什么它可能想要这样做,留给读者作为练习......)。 所有这一切都是可能的,而不需要将按钮细分为一个狭窄的专业。

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.

聊慰 2024-07-28 05:04:58

这是因为相同的 DependencyProperty 可以针对多种类型进行不同的定义(使用不同的元数据)

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

乖乖兔^ω^ 2024-07-28 05:04:58

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

In a nutshell, when you're registering a DP, you're adding an object(DP) to a list attached to a class(owner). This operation only "lives" in the class where it is declared and often is not related to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文