何时应该在WPF中使用依赖属性?

31

在WPF中何时应使用依赖属性?

与使用.NET属性相比,它们是静态的,因此我们可以节省大量内存。 使用依赖属性而不是.NET属性的其他优点包括: 1)无需检查线程访问 2)促使包含元素呈现 等等......

所以看起来在我使用WPF的项目中,我应该总是使用依赖属性?

也许对于一些辅助类的琐碎属性,我可以使用.NET属性……


https://dev59.com/aFTTa4cB1Zd3GeqPwuWb什么是依赖属性,何时使用?依赖属性是一种特殊类型的属性,可用于在 WPF 中实现多种功能。它们允许您设置值,这些值可以从多个源继承,并且可以在更改时自动更新。例如,当您更改窗口的大小时,WPF 可以自动调整其子元素的大小。依赖属性还可以用于数据绑定、样式和动画等方面。https://dev59.com/NXRB5IYBdhLWcg3wc3A0什么是依赖属性?依赖属性是一种特殊类型的属性,可用于在 WPF 中实现多种功能。它们允许您设置值,这些值可以从多个源继承,并且可以在更改时自动更新。例如,当您更改窗口的大小时,WPF 可以自动调整其子元素的大小。依赖属性还可以用于数据绑定、样式和动画等方面。 - Nitesh
一个重要的事情是,依赖属性只能用于继承自DependencyObject的对象上。这也是不在ViewModels中使用它们的原因,因此在WPF项目中也不总是使用。此外,它们还会对性能产生一定的影响。 - dowhilefor
我不确定你为什么说“不需要检查线程访问”?据我所知,如果你从另一个线程而非UI线程设置依赖属性的值,则会抛出异常。 - AH.
依赖属性不是静态的,也不保存任何内存。只有属性的定义是静态的。所有依赖属性都绑定到对象引用,因此每个实例的属性确实占用一部分内存。 - Christian Findlay
6个回答

20

依赖属性是一个广泛的概念,解释起来可能需要写几页纸。所以为了回答你的主要问题,依赖属性用于以下情况:

  1. 您知道该属性将成为绑定目标,即您正在创建一个用户控件/自定义控件,并希望该属性应该由绑定驱动。

  2. 您想要自动属性更改通知(包括强制和验证)。

  3. 我们想要在样式、主题、父节点或默认值中进行值继承。

  4. 大多数情况下,我们不需要在模型或视图模型层创建依赖属性作为属性,因为这不会在内存节省方面有太大的帮助,因为我们在模型/VM中定义的大多数属性将具有每个实例的值,因为它们将不断更改。依赖属性值的解析本身就是一种负担,因此不建议不必要地使属性依赖。

谢谢


是的,样式和动画是必须使用依赖属性的一个场景。 - user2381422
当您想要通过XAML绑定其值时,也应该使用它。 - Ahmed Ahmed
这不是一个完整的答案。基本上,您需要为您想在XAML中使用的所有属性定义依赖属性。这是与Silverlight的主要区别点,后者允许您在XAML中使用普通属性。 - Christian Findlay

18

创建DependencyProperty的主要原因是当您编写自己的WPF控件时。

DependencyProperties可用作绑定源和目标,并且可以进行动画处理。 所有框架控件的属性都被实现为DependencyProperty,这就是为什么您可以在XAML中进行强大的数据绑定。

然而,在大多数情况下,例如在MVVM模式中,您不需要依赖属性,INotifyPropertyChanged就足够了。


11
主要区别在于,普通的.NET属性的值直接从类中的私有成员读取,而DependencyProperty的值在调用从DependencyObject继承的GetValue()方法时动态解析。
当您设置依赖项属性的值时,它不会存储在对象的字段中,而是存储在由基类DependencyObject提供的键值字典中。条目的键是属性的名称,值是要设置的值。
依赖属性的优点是:
  1. 内存占用减少:
    当你考虑到 UI 控件中超过90%的属性通常保持其初始值时,为每个属性存储一个字段是一种巨大的浪费。依赖属性通过仅在实例中存储修改后的属性来解决这些问题。默认值仅在依赖属性中存储一次。
  2. 值继承:
    当访问依赖属性时,使用值分辨策略解析值。如果未设置本地值,则依赖属性向上导航逻辑树直到找到值。当在根元素上设置FontSize时,它应用于所有下面的文本块,除非你覆盖该值。
  3. 更改通知:
    依赖属性具有内置的更改通知机制。通过在属性元数据中注册回调,您将在属性值更改时获得通知。这也被数据绑定使用。

查看以下网址以了解其中的神奇:

WPF 中的依赖属性


15
你基本上是复制了MSDN文档,但没有提供有用的评论。是的,这些东西都很好,但你有什么建议,是应该总是使用依赖属性吗? - user2381422

7

输入图像描述

CLR 属性 vs. 依赖属性

CLR 属性直接从类的私有成员中读取。类的 Get() 和 Set() 方法检索和存储属性的值。 而当您设置依赖属性的值时,它不会存储在对象的字段中,而是存储在由基类 DependencyObject 提供的键和值字典中。条目的键是属性的名称,值是要设置的值。

依赖属性的优点 内存消耗更少

依赖属性仅在修改或更改时才存储属性。因此,大量用于字段的内存被释放。

属性值继承 如果未为属性设置任何值,则它将返回到继承树,直到获取值为止。

更改通知和数据绑定 每当属性更改其值时,在 Dependency Property 中使用 INotifyPropertyChange 提供通知,并帮助进行数据绑定。

参与动画、样式和模板 依赖属性可以通过样式设置器来设定动画、样式甚至控件的模板。

回调 每当更改属性时,您可以调用回调函数。

资源 您可以在 XAML 中定义依赖属性的定义资源。

覆盖元数据 使用 PropertyMetaData 可以定义依赖属性的某些行为。因此,从派生属性覆盖元数据不需要重新定义或重新实现整个属性定义。


“一个CLR属性直接从类的私有成员中读取”这是完全错误的。CLR属性映射到getter/setter函数。 - cdiggins

3
也许您应该再看一下MSDN上的Dependency Properties Overview页面。个人而言,只有在我真正需要时才会创建一个DependencyProperty。在数据类型和视图模型类中,我大多数情况下使用普通的CLR属性进行绑定... 只要我实现了INotifyPropertyChanged接口,这是完全可以的。因此,对于我所有的常规数据绑定,我使用普通的CLR属性。我仅在需要为UserControl提供一些附加功能时才声明Dependency Property

2
依赖属性(Dependency properties)用于在UserControl中进行数据绑定,是WPF框架控件的标准数据绑定方法。DP具有稍微更好的绑定性能,并且在UserControl内部实现它们时提供了所有必要的内容。
否则,通常在其他地方使用INotifyPropertyChanged进行绑定,因为在独立类中实现它更容易,并且开销更小。至于您最初的假设:
  1. 有一个变量的本地实例,与属性相比,您绝对不会节省任何开销,因为内置了大量的数据绑定逻辑。
  2. 它们必须在主线程上访问

这不正确,至少不够精确。是的,依赖属性可以用于UserControls,但也可以用于CustomControls和基本上从DependencyObject派生的任何对象。 - dowhilefor

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