我什么时候应该在WPF中使用依赖属性?
我什么时候应该在WPF中使用依赖属性?
它们是静态的,因此与使用.NET属性相比,我们在内存上节省了很多。 在.NET属性上使用依赖项属性的其他好处是:1)不需要检查线程访问2)提示要包含的元素等…
所以我似乎总是应该在我使用WPF的项目中使用依赖属性?
也许对于帮助类的一些微不足道的属性,我可以摆脱.NET属性……
依赖属性是一个广泛的概念,可以解释哪些页面可能需要编写几页。 所以只是回答你的主要问题,在哪里使用Dependency属性
-
您知道该属性将成为绑定目标,即您正在创建用户控件/自定义控件并希望属性应该是绑定驱动的。
-
您想要自动属性更改通知(也是coerse和validation)。
-
我们希望在样式,主题,父级或默认值中inheritance值。
-
在大多数情况下,不需要在Model或ViewModel层上创建属性作为依赖属性,因为这对内存节省不会有太大帮助,因为我们在model / VM中定义的大多数属性将具有每个实例的值,因为它们将不断变化。 解决依赖属性值本身就是一种负担,因此不建议不必要地产生属性依赖性。
谢谢
创建DependencyProperty
主要原因是您编写自己的WPF控件。 DependencyProperties
可以用作绑定源和目标,并且可以设置动画。 所有框架控件的属性都实现为DependencyProperty
,这就是为什么你可以在XAML中进行强大的数据绑定的原因。
但是在大多数情况下,就像使用MVVM模式一样,您不需要依赖属性, INotifyPropertyChanged
就足够了。
主要区别在于,正常.NET属性的值是直接从类中的私有成员读取的,而DependencyProperty的值是在调用从DependencyObjectinheritance的GetValue()方法时动态解析的。
设置依赖项属性的值时,它不存储在对象的字段中,而是存储在基类DependencyObject提供的键和值的字典中。 条目的键是属性的名称,值是您要设置的值。
依赖属性的优点是
- 减少内存占用:
当您认为UI控件的90%以上的属性通常保持其初始值时,为每个属性存储字段是一个巨大的耗散。 依赖项属性仅通过在实例中存储已修改的属性来解决这些问题。 默认值在依赖项属性中存储一次。 - 价值inheritance:
访问依赖项属性时,将使用值解析策略解析该值。 如果未设置本地值,则依赖项属性将向上导航逻辑树,直到找到值。 当您在根元素上设置FontSize时,它将应用于下面的所有文本块,除非您覆盖该值。 - 变更通知:
依赖项属性具有内置的更改通知机制。 通过在属性元数据中注册回调,您可以在更改属性的值时收到通知。 这也用于数据绑定。
请查看以下url,了解有关魔术的更多详情
WPF中的依赖项属性
CLR属性与依赖属性
CLR属性直接从类的私有成员读取。 该类的Get()和Set()方法检索并存储属性的值。 而当您设置依赖项属性的值时,它不会存储在对象的字段中,而是存储在基类DependencyObject提供的键和值的字典中。 条目的键是属性的名称,值是您要设置的值。
依赖属性的优点减少内存消耗
Dependency Property仅在更改或修改属性时才存储该属性。 因此,字段的大量内存是免费的。
属性值inheritance这意味着如果没有为属性设置值,那么它将返回到inheritance树,直到获取值。
更改通知和数据绑定每当属性更改其值时,它都会使用INotifyPropertyChange在Dependency属性中提供通知,并且还有助于数据绑定。
参与动画,样式和模板依赖属性可以使用样式设置器设置动画,设置样式,甚至可以为控件提供模板。
CallBacks每当更改属性时,您都可以调用回调。
资源您可以为XAML中的依赖项属性定义定义资源。
覆盖元数据您可以使用PropertyMetaData定义依赖项属性的某些行为。 因此,从派生属性覆盖元数据将不需要您重新定义或重新实现整个属性定义。
当您希望在UserControl
数据绑定时,将使用依赖项属性,并且它是WPF Framework控件的标准数据绑定方法。 DP具有稍好的绑定性能 ,并且在UserControl
内部实现它们时会提供所有内容。
否则,您通常使用INotifyPropertyChanged
在其他地方进行绑定,因为它在独立类中实现起来更容易,并且开销更少。 至于你原来的假设:
- 有一个变量的本地实例,你绝对不会在属性上节省任何开销,因为内置了重要的数据绑定逻辑。
- 必须在主线程上访问它们 。
也许您应该再看一下MSDN上的Dependency Properties Overview页面。
就个人而言,我只会在真正需要的时候创建一个DependencyProperty
。 在大多数情况下,我使用数据类型和视图模型类中的普通CLR属性来绑定到…这绝对没问题,只要我实现INotifyPropertyChanged
接口。
因此,对于我所有常用的数据绑定,我使用普通的CLR属性。 我只声明一个Dependency Property
,以便在UserControl
提供一些附加function。