【问题标题】:What is the difference between Property and Dependency Property属性和依赖属性有什么区别
【发布时间】:2010-09-09 07:05:10
【问题描述】:

依赖属性的创建方式与属性相同。

依赖属性是否仅在创建自定义控件时使用?

【问题讨论】:

    标签: c# wpf silverlight dependency-properties


    【解决方案1】:

    依赖属性和标准属性有很大的不同。

    依赖属性提供的关键特性是支持绑定动画。如果要使用 Binding 或模板绑定为属性分配值,则该属性需要是依赖项属性。动画属性时,依赖属性可以跟踪当前分配的值和当前动画值。

    另一个经常被忽视的优点是只有分配了值的属性才需要存储。一个典型的控件可以有很多属性,但很少有代码为所有属性分配一个新值,事实上,大多数属性都保留为默认值,实际设置的属性很少。对于依赖属性,默认值存储为与属性相关的元数据,并且如果该属性仍未分配,则不需要为每个控件实例分配任何内存。

    依赖属性不限于控件(从DependencyObject 派生的任何东西都可以拥有它们),但它在控件上或至少在它们最有用的FrameworkElements 上。

    【讨论】:

    • +1:这得到了我的投票,因为它实际上回答了所提出的问题
    【解决方案2】:

    依赖属性的优点

    事实上,依赖属性比普通的 CLR 属性有很多优势。

    1. 属性值继承: 属性值继承是指可以在层次结构中覆盖依赖属性的值,从而最终设置具有最高优先级的值。
    2. 数据验证:我们可以强制在属性值被修改时自动触发数据验证。
    3. 参与动画:依赖属性可以动画。 WPF 动画有很多功能可以按时间间隔更改值。定义一个依赖属性,你最终可以支持该属性的动画。
    4. 参与样式:样式是定义控件的元素。我们可以在依赖属性上使用样式设置器。
    5. 参与模板:模板是定义元素整体结构的元素。通过定义 Dependency 属性,我们可以在模板中使用它。
    6. DataBinding : 由于每个 Dependency 属性本身都会在属性值被修改时调用 INotifyPropertyChanged,因此内部支持 DataBinding。要阅读有关INotifyPropertyChanged 的更多信息,请阅读。
    7. CallBacks : 您可以对依赖属性进行回调,以便每当更改属性时,都会引发回调。
    8. Resources: Dependency 属性可以采用 Resource。所以在 XAML 中,你可以定义一个 Resource 来定义一个 Dependency 属性。
    9. 元数据覆盖:您可以使用 PropertyMetaData 定义依赖属性的某些行为。因此,从派生属性覆盖元数据将不需要您重新定义或重新实现整个属性定义。
    10. 设计器支持: 依赖属性获得 Visual Studio 设计器的支持。您可以看到在设计器的属性窗口中列出的控件的所有依赖项属性。

    在这些中,某些功能仅受依赖属性支持。 AnimationStylesTemplates、属性值继承等只能使用依赖属性参与。如果在这种情况下使用 CLR 属性,编译器将产生错误。

    请浏览这些文章,

    http://www.codeproject.com/KB/WPF/BeginWPF4.aspx#diff

    http://www.dotnetfunda.com/articles/article961-wpf-tutorial--dependency-property-.aspx

    http://msdn.microsoft.com/en-us/library/cc221408(VS.95).aspx

    【讨论】:

    • 很多这些“优势”是有争议的。例如,标准属性可以运行代码来验证分配的值。底线是依赖属性做了两个关键的事情,支持绑定和允许动画。
    【解决方案3】:

    依赖属性是注册另一个属性的属性(不是自身,而是依赖于另一个,比如 XAML 绑定属性)。

    dependecy 属性通过注册在后面的代码中注册另一个绑定属性。我的项目中使用的一个例子如下:

    public static DependencyProperty ImageUri = DependencyProperty.Register("Source", typeof(BitmapImage), typeof(CustomImagePlaceHolder), new PropertyMetadata(null));
    

    在上面的代码中,ImageUri 是一个注册 Source 的依赖属性,它在 generic.xaml 中定义/声明(无论是声明、定义还是其他),如下所示:

    ..HorizontalAlignment="Center"
    VerticalAlignment="Center"
    Height="{TemplateBinding Height}"
    Width="{TemplateBinding Width}"
    />
    

    所以这里非常重要的是,XAML 中的模板绑定值应该在后面的代码中注册为依赖属性。

    所以当我们在 XAML 中定义 Image Source 应该与 Source 模板绑定时,我们已经注册了相同的 Source 作为 DependencyProperty。

    我们得说是哪种类型的依赖属性,上面例子中Source是BitmapImage的类型,所以我们定义了typeof(BitmapImage)。

    现在这个依赖属性的所有者/父级是我们的 customControlClass CustomImagePlaceHolder,我们在注册时再次定义了它。

    现在设置依赖属性的值,使用我们的属性如下:

    public BitmapImage Source
            {
                get
                {
    
       string strURI = (string)GetValue(CustomImagePlaceHolder.ImageUri);
                    return new BitmapImage(new Uri(strURI));
                }
                set
    {
    SetValue(CustomImagePlaceHolder.ImageUri, value);
     }
    
            }
    

    现在是这样的,我们将后面的代码或 xaml 中的值设置为上面定义的 source 属性,然后设置依赖属性 ImageUri 的值,该属性又设置模板绑定 Source 中的值,因为我们已将 ImageUri 注册为 Source,即存在 generic.xaml。

    【讨论】:

      【解决方案4】:

      依赖项 droperty 和标准 clr 属性之间的主要区别在于,依赖项属性可以是绑定的目标。这允许您将属性的值与其他对象提供的值联系起来。

      我建议,如果您正在制作自定义控件或标记扩展,您通常希望将其任何公共属性公开为依赖属性,以便您的控件的使用者可以更好地操作 XAML 中的设置(无需这样做它在代码隐藏中)。

      如果您的属性通常是数据绑定的来源(例如,为 TextBlock 提供文本),我建议使用标准 CLR 属性并让包含类实现 INotifyPropertyChanged。

      进一步......

      相对于由字段支持的属性,依赖属性提供了扩展属性功能的功能。通常,每个此类功能都代表或支持整个 WPF 功能集的特定功能。

      资源

      数据绑定

      样式

      动画

      元数据覆盖

      属性值继承

      http://msdn2.microsoft.com/en-us/library/ms752914.aspx

      希望这会有所帮助。

      【讨论】:

        【解决方案5】:

        如果你在 VS 编辑器中输入 propdp 并点击 tab 字符,那么 Dependency Properties 的自动生成文档设置为:

        // 使用 DependencyProperty 作为 MyProperty 的后备存储。
        这可以启用动画、样式、绑定等...

        【讨论】:

          猜你喜欢
          • 2011-05-12
          • 1970-01-01
          • 2011-11-14
          • 2011-01-20
          • 2010-09-20
          • 2016-04-29
          • 2018-04-28
          相关资源
          最近更新 更多