Silverlight中附加和非附加依赖属性的区别

Mel*_*ron 13 c# silverlight dependency-properties attached-properties

好的Stackers,我在这个问题上花了好几个小时,我想知道是否有人有明确的答案.
对于所有的研究,我已经做了,我找不到任何区别.Register,并.RegisterAttachedSilverlight中.现在,在你跳枪并告诉我.RegisterAttached用于将DP附加到另一个类之前,尝试使用实现附加的依赖属性DependencyProperty.Register().我发现没有一个区别,所以我不知道有什么区别.
此外,在我的具体情况下,我试图扩展Grid类的功能,并希望给它一些额外的属性.因此,我尝试列出传递两者typeof(Grid)typeof(FluidLayoutManager)(实现类)作为ownerType参数,它似乎也没有什么区别...(我相信当我从同一名称空间传递两个自定义类时它确实有所作为但是,当传递Microsoft定义的类与自定义类时,我总是将它作为自定义类的DP显示在XAML中.)
对此主题的任何澄清将非常感激,因为我坐在这里抓我的头,并想知道是否有任何差异,或者微软是否只是再次与我搞砸了.

Gon*_*ing 9

考虑到评论中的讨论,我将尝试用简单的英语做这个:

附加依赖项属性和依赖项属性之间的主要区别(因此介于.Register和.RegisterAttached之间)是RegisterAttached允许将值分配给任何依赖项对象,而Register仅允许将它附加到作为ownerType参数传递的类.

正如Haris Hasan所提到的(在评论主题的深处),您的示例使用了唯一允许的类型(即CustomControl),并没有向您显示可以将附加版本分配给任何依赖项对象.

例如,您可以使用附加依赖属性(但不是普通DP)执行此操作:

<Grid local:AttacherClass.ADP1="1" x:Name="LayoutRoot" Background="White">
</Grid>
Run Code Online (Sandbox Code Playgroud)

我能找到的ADP的最佳参考是这个:http://msdn.microsoft.com/en-us/library/ms749011.aspx

我们使用ADP作为定位系统的基础,因此翻译可以在加载期间寄生在对象上,而不是使用可怕的长绑定.不能用DP做到这一点

更新:

我还想澄清一下,父限制适用于基于XAML的属性使用.从代码来看,父限制显然不适用.

  • **进一步的XAML信息1**:XAML使用`SetDP/ADP()`和`GetDP/ADP()`函数,但是调用`SetValue(DP/ADP,value)`和`GetValue(DP/ADP) )`不要.**2:**在XAML Designer中,Intellisense将使用`SetDP/ADP()`和`GetDP/ADP()`方法签名来确定是否显示依赖属性或附加依赖属性.因此,如果`SetDP/ADP()`参数接受`DependencyObject`而不是更具体的类,它将显示无效的依赖属性. (2认同)

srg*_*stm 6

认为"RegisterAttached允许将值分配给任何依赖项对象而Register只允许将其附加到作为ownerType参数传递的类"是错误的.以下是在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));
    }
}
Run Code Online (Sandbox Code Playgroud)

Reflector显示Register和RegisterAttached之间的唯一区别是Register抛出了大部分提供的元数据,并且仅为注册类的实例保留它(通过OverrideMetadata).这意味着通常在元数据中指定的继承和各种更新通知等属性不适用于使用Register注册并附加到其他类型的对象(注册类型除外)的属性.所以Register实际上是RegisterAttached的精简版本.出于性能原因,它可能是这样做的.

在Haris Hasan在他的回答评论中链接的示例中,如果您将RegisterAttached更改为Register,按钮将停止移动(因为该属性不再为Button类型提供AffectsParentArrange元数据)但是当您调整大小时它们仍会在新位置重绘窗户.但是,如果在调用InitializeComponent()之后向Button类型添加相同的元数据:

RadialPanel.AngleProperty.OverrideMetadata(
    typeof(Button), 
    new FrameworkPropertyMetadata(
        0.0, FrameworkPropertyMetadataOptions.AffectsParentArrange));
Run Code Online (Sandbox Code Playgroud)

然后一切都再次起作用,就像调用了RegisterAttached一样.


Har*_*san 5

就实施而言,它们可能没有太大的不同,但它们在行动上是不同的,即它们的作用和用途不同.

Simple Register用于简单的依赖项属性,通常用于绑定和验证,因此它们是正常的CLR属性,带有一些额外的魔法,有助于WPF

RegisterAttached通常用于您希望公开可以在子类中访问和设置的属性的位置,例如DockPanel控件的子级告诉父级要使用Dock.Left或在哪里放置它们Dock.Right.所以它们是一种特殊的依赖属性,可以在子控件中访问(不是简单Register属性的情况),它们(如果有DockPanel)帮助父控件显示子节点

简而言之,一个cay说Register是使用注册dependency properties,它们在同一个类中使用,同时RegisterAttached用于注册被调用的特殊依赖项属性attached properties,它们被除了定义它之外的类使用和访问

是对附加属性的一个很好的解释,以及通过简单DP无法实现的内容