【问题标题】:When should I use dependency properties in WPF?什么时候应该在 WPF 中使用依赖属性?
【发布时间】:2021-09-10 23:33:57
【问题描述】:

什么时候应该在 WPF 中使用依赖属性?

它们是静态的,因此与使用 .NET 属性相比,我们可以节省大量内存。 使用依赖属性而不是 .NET 属性的其他好处是: 1)无需检查线程访问 2) 提示一个包含元素被渲染 等等……

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

也许对于助手类的一些琐碎属性我可以 摆脱 .NET 属性...

【问题讨论】:

  • 重要的是,依赖属性只能用于从 DependencyObject 继承的对象。不在 ViewModel 上使用它们的原因之一,因此并不总是在 WPF 项目中。它们对性能的影响也很小。
  • 我不知道你为什么说“不需要检查线程访问”?据我所知,如果您从另一个线程而不是 UI 线程设置依赖属性的值,则会引发异常。
  • 依赖属性不是静态的,不会节省任何内存。只有属性的定义是静态的。所有依赖属性都绑定到一个对象引用,因此该属性确实会为每个实例占用一块内存。

标签: c# wpf


【解决方案1】:

依赖属性是一个宽泛的概念来解释它可能需要几页来编写。所以只是为了回答你的主要问题,依赖属性在哪里使用

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

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

  3. 我们希望在样式、主题、父级或默认值中继承值。

  4. 大多数时候不需要在 Model 或 ViewModel 层上创建属性作为依赖属性,因为这对节省内存没有太大帮助,因为我们在 model/VM 中定义的大多数属性都会每个实例都有值,因为它们会不断变化。解析 Dependency 属性值本身就是一种负担,因此不建议不必要地进行属性依赖。

谢谢

【讨论】:

  • 是的,样式和动画是您必须使用依赖属性的一种上下文。
  • 当您希望能够通过 XAML 绑定其值时,也应该使用它。
  • 这不是一个完整的答案。您基本上需要为要在 XAML 中使用的所有属性定义依赖项属性。这是与 Silverlight 的主要区别,它允许您在 XAML 中使用普通属性。
【解决方案2】:

创建DependencyProperty 的主要原因是当您编写自己的 WPF 控件时。 DependencyProperties 可以作为绑定源和目标,并且可以动画。 所有框架控件的属性都实现为DependencyProperty,这就是为什么您可以在XAML中进行强大的数据绑定。

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

【讨论】:

    【解决方案3】:

    主要区别在于,普通 .NET 属性的值是直接从类中的私有成员读取的,而 DependencyProperty 的值是在调用从 DependencyObject 继承的 GetValue() 方法时动态解析的。

    当您设置依赖属性的值时,它不会存储在对象的字段中,而是存储在基类 DependencyObject 提供的键和值的字典中。条目的键是属性的名称,值是您要设置的值。

    依赖属性的优点是

    1. 减少内存占用:
      当您认为 UI 控件的 90% 以上的属性通常保持其初始值时,为每个属性存储一个字段是一种巨大的浪费。依赖属性通过仅将修改后的属性存储在实例中来解决这些问题。默认值在依赖属性中存储一次。
    2. 值继承:
      当您访问依赖项属性时,使用值解析策略来解析值。如果没有设置本地值,则依赖属性会向上导航逻辑树,直到找到一个值。当您在根元素上设置 FontSize 时,它​​适用于下面的所有文本块,除非您覆盖该值。
    3. 更改通知:
      依赖属性具有内置的更改通知机制。通过在属性元数据中注册回调,您会在属性值发生更改时收到通知。这也被数据绑定使用。

    查看下面的网址了解更多关于它背后的魔法的详细信息

    dependency properties in WPF

    【讨论】:

    • 你基本上复制了这里的 msdn 文档而没有给出有用的评论。是的,所有这些都很好,但是你有什么建议,总是使用依赖属性?
    【解决方案4】:

    CLR 属性与依赖属性

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

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

    依赖属性仅在更改或修改时存储属性。因此,大量的字段内存是空闲的。

    属性值继承 这意味着如果没有为属性设置值,那么它将返回到继承树,直到它获取值。

    更改通知和数据绑定 每当属性更改其值时,它都会使用 INotifyPropertyChange 在 Dependency Property 中提供通知,并且还有助于数据绑定。

    参与动画、样式和模板 依赖属性可以设置动画,使用样式设置器设置样式,甚至为控件提供模板。

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

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

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

    【讨论】:

    • “CLR 属性直接从类的私有成员中读取。”这是完全错误的。 CLR 属性映射到 getter/setter 函数。
    【解决方案5】:

    也许您应该再看看 MSDN 上的 Dependency Properties Overview 页面。

    就个人而言,我只会在我真正需要时创建DependencyProperty。在大多数情况下,我在数据类型和视图模型类中使用普通的 CLR 属性来绑定……这绝对没问题,只要我实现了INotifyPropertyChanged 接口。

    所以对于我所有常用的数据绑定,我使用普通的 CLR 属性。我声明了一个Dependency Property,以便在UserControl 中提供一些附加功能。

    【讨论】:

      【解决方案6】:

      当您希望在UserControl 中进行数据绑定时使用依赖属性,它是 WPF 框架控件数据绑定的标准方法。 DP 有slightly better binding performance,当在UserControl 中实现它们时,所有东西都提供给你。

      否则,您通常使用INotifyPropertyChanged 在其他地方进行绑定,因为它更容易在独立类中实现并且开销更少。就您最初的假设而言:

      1. 您的变量有一个本地实例,您绝对不会为属性节省任何开销,因为内置了重要的数据绑定逻辑。
      2. They must be accessed on the main thread.

      【讨论】:

      • 那不正确,至少不准确。是的,依赖属性可以用在 UserControls 上,也可以用在 CustomControls 上,基本上每个派生自 DependencyObject 的对象。
      猜你喜欢
      • 2012-06-10
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-25
      • 1970-01-01
      • 2012-01-17
      相关资源
      最近更新 更多