DependencyProperty.Register() 或 .RegisterAttached()

43
这两者有什么区别,何时应该使用RegisterAttached()而不是.Register()?
4个回答

57

我假设您想表达的是DependencyProperty.Register和DependencyProperty.RegisterAttached。

DependencyProperty.Register用于注册普通的DependencyProperty。你可以将其视为普通属性,额外增加了WPF数据绑定、动画等功能。 实际上,在未经类型化的DependencyObject.SetValue / GetValue之上,它们作为普通属性(具有get和set访问器)公开。 您在类型中声明这些内容。

另一方面,附加属性则不同。它们被设计为一种扩展系统。如果您曾经使用过Windows Forms中的Extenders,它们有点类似。 您将它们声明为类型的一部分,以在另一个类型上使用。

它们在布局相关信息中经常用到。例如,Canvas需要Left/Top坐标,Grid需要行和列,DockPanel需要停靠信息等。如果所有这些都必须在每个可布局的控件上声明,那就会很混乱。因此,它们在相应的面板上声明,但在任何控件上使用。

如果需要,您可以使用相同的方法将任何信息附加到DependencyObject上。如果您只需声明一条信息以在现有类的样式中稍后使用,则可能会派上用场。

因此,这两种DependencyProperty的作用非常不同。通过Register()注册的常规属性与类型的接口一样使用。通过RegisterAttached()注册的附加属性用作现有类上的扩展点。

希望能澄清一些问题。


1
那么,attach 可以用于向你不拥有的类添加属性?这就是区别吗? - Vaccano
2
你也可以在其他对象上设置非附加属性的依赖属性:this.button.SetValue(TextBox.TextProperty, "text");(其中 this.button 的类型为 System.Windows.Controls.Button)。这是完全可以的,所以答案还不够完整。肯定还有更多的内容。 - bitbonk

13
DependencyProperty.Register()和DependencyProperty.RegisterAttached()的区别在于,.Register()用于在DependencyObject上注册“常规”依赖属性,而.RegisterAttached()用于设置“附加”依赖属性。
这两种类型的依赖属性的区别相对简单:普通依赖属性像.NET属性一样设置在特定的DependencyObject上。另一方面,附加属性与特定的DependencyObject(例如Grid)相关联,但是在完全不同的DependencyObject上设置,通常是定义附加属性的DependencyObject的子项(例如Grid.Row是一个附加属性,在父Grid的子项上设置)。
更多关于附加属性的详细信息请参阅MSDN

5
使用Register或RegisterAttached注册的属性可以使用SetValue和GetValue附加到任何DependencyObject上。但是,如果您将使用Register注册的属性附加到除ownerType以外的其他类型对象上,则其元数据将不会被使用(除了默认值)。这意味着像Inherits或AffectsMeasure等属性对这些属性无效。如果您想要使用附加属性上的元数据,应该使用RegisterAttached。
有关详细信息,请参阅我的类似问题的答案:Silverlight中依赖项属性的附加和非附加属性之间的区别

0
在我的情况下,RegisterAttached 只设置了一次绑定字段,而 Register 按预期动态工作。
这是从一个场景中提取的,其中列表中的按钮需要在鼠标悬停时显示预览,并且已经使用了 CommandParam
public static DependencyProperty MouseCommandParamProperty = DependencyProperty.Register(
                                                                        "MouseCommandParam",
                                                                        typeof(object),
                                                                        typeof(MouseBehaviour),
                                                                        new PropertyMetadata(defaultValue:null, new PropertyChangedCallback(MouseCommandParamChanged)));
        public static void SetMouseCommandParam(DependencyObject target, object value)
        {
            target.SetValue(MouseBehaviour.MouseCommandParamProperty, value);
        }
        public static object GetMouseCommandParam(DependencyObject target)
        {
            return (object)target.GetValue(MouseBehaviour.MouseCommandParamProperty);
        }
        private static void MouseCommandParamChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
        {
            UIElement element = target as UIElement;
            if (element != null)
            {
                element.SetValue(MouseBehaviour.MouseCommandParamProperty, e.NewValue);
            }
        }

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