.net – 神秘依赖属性

前端之家收集整理的这篇文章主要介绍了.net – 神秘依赖属性前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经在SO和其他网站上看过关于依赖属性的很多。但是,真的没有找到一个很好的解释,我仍然感到困惑。我使用SL和WPF。在SL和WPF中是否有所不同?为什么我们真的需要它们?他们的静态意味着他们的价值观被分享吗?为什么MS引入了依赖属性

赏金:
我正在寻找一个更彻底,完整的答案。

答案是名称本身,虽然“依赖”一词在软件开发中充满意义,但这并不是特别明确的。

依赖属性是一个对象的属性,其值取决于某个其他对象。所以,例如:

> TextBox的FontFamily属性的值可以(通常也可以)取决于其容器的FontFamily属性。如果更改容器上的属性,则TextBox上的值将更改。
> TextBox的Text属性的值可以取决于绑定的数据源。当绑定属性的值更改时,Text属性的值会更改。
>标签的Opacity属性的值可以取决于动画故事板,在常见的情况下,您已经设置了一个UI元素来淡出或淡出以响应某些事件。
>任何UI元素上各种属性的值可以取决于您应用于它们的样式。

依赖关系的中心概念是,依赖的东西应该从它所依赖的东西获得属性值。这就是为什么一个依赖属性被实现为一个CLR属性,其getter调用一个方法

当TextBox或其渲染的东西需要知道FontFamily是什么,FontFamily getter调用GetValue方法。该方法从容器,动画或绑定或其他方法中找到值。

方法有很多复杂性。例如,如果值继承,它的工作方式与WPF在资源字典中找到样式非常相似:它会在本地字典中查找该值,如果没有条目,它会在其父字典中查找,并且所以一直到找到一个值或达到层次结构的顶部,在这种情况下,它使用一个默认值。

如果你看看依赖属性的实现,那就是你会发现的。依赖对象具有可以包含或可以不包含给定属性的条目的字典。 GetValue方法从该字典获取值(依赖属性的对象如何具有覆盖它们所继承的本地值的本地值),如果没有找到该值,它将使用关于该属性的元信息来计算应该在哪里看

由于该类信息对于类中的每个对象都是相同的(即TextBox.Text对于每个TextBox都是相同的),所以存储在其中的字典是该类的静态属性

所以当你看到这样的代码

static Button()
{
   // Register the property
   Button.IsDefaultProperty = 
     DependencyProperty.Register("IsDefault",typeof(bool),typeof(Button),new FrameworkPropertyMetadata(false,new PropertyChangedCallback(OnIsDefaultChanged)));
}

发生的是在所有Button对象中定义IsDefault属性的元信息都被添加到该字典中。当你看到这个:

public bool IsDefault
{
  get { return (bool)GetValue(Button.IsDefaultProperty); }
  set { SetValue(Button.IsDefaultProperty,value); }
}

你看到的是getter方法,它根据该元信息查找属性的值(来自本地字典,父对象或其他)。

记住我如何说,getter看起来找到一个属性的值的第一个地方在对象的本地字典中? setter中的SetValue方法是如何将这个条目添加到字典中(如果它被调用,那么只有当你通过显式地设置属性来覆盖依赖关系时,就是说“我希望这个TextBox能够显示文本Consolas,而不管窗口中的其他控件使用什么。“)。

我们从这种显然复杂的系统中获得的巨大优势是,对象的依赖属性只有在设置时才消耗内存。如果我创建10,000个TextBox控件并将它们添加到一个窗口中,其中一个实际上不包含对FontFamily对象的引用。这是10,000个对象引用,我没有分配内存,垃圾收集器没有检查。实际上,如果一个TextBox有100个依赖属性(而且它只是大约),每当你创建一个TextBox,这是100个后备字段,你不分配内存。如果您明确设置它们,则依赖属性仅消耗内存。由于UI对象的绝大多数属性从未被明确设置,所以这些都是非常好的节省。

猜你在找的设计模式相关文章