我在 Stack Overflow 和其他网站上读了很多关于依赖属性的文章,但是仍然感到困惑,没有找到一个好的解释。我同时使用 Silverlight (SL) 和 Windows Presentation Foundation (WPF),它们的实现方式是否不同?我们真正需要它们吗?它们是否静态的,也就是说它们的值是共享的?为什么微软要引入依赖属性呢?
我在 Stack Overflow 和其他网站上读了很多关于依赖属性的文章,但是仍然感到困惑,没有找到一个好的解释。我同时使用 Silverlight (SL) 和 Windows Presentation Foundation (WPF),它们的实现方式是否不同?我们真正需要它们吗?它们是否静态的,也就是说它们的值是共享的?为什么微软要引入依赖属性呢?
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); }
}
您所看到的是获取器方法,它基于元信息查找属性值(从本地字典、父对象或其他地方)。您可能还记得我之前提到过,获取器查找属性值的第一个位置是对象的本地字典。设置器中的 "SetValue" 方法是将该条目添加到字典中(仅在需要覆盖依赖项并显式设置属性时才会调用,即说“我想让此文本框显示 Consolas 字体,而与窗口中的其他控件使用的字体无关。”)。其他人已经对依赖属性进行了解释。我将尝试提供一些关于它们设计的背景信息。(这有助于我理解为什么首先存在这些奇怪的称为依赖属性的创建物。) WPF 设计者添加依赖属性而不是使用普通属性有几个原因...
如果微软像迭代器一样使用编译器魔法来隐藏重复的代码,为创建新依赖属性提供更好的语法将会很好。也许在 C# 6 中... :)
它们在SL和WPF中是否有区别?
没有
我们真正需要它们的原因是什么?
简短的答案是,我们需要它们来进行数据绑定和样式设置,这也是微软添加它们的原因。
它们是静态的,这意味着它们的值是共享的吗?
静态部分是属性的名称,因此可以使用GetValue(propName)检索它的值,并使用SetValue(propName, value)进行设置。
请注意,依赖属性通常由CLR属性支持,这意味着您可以像使用CLR属性一样在代码中与其交互。
WPF是围绕属性架构设计的,需要一个非常强大的属性系统来支持:
我发现以下文章非常有用 -
WPF中的依赖属性概述: http://joshsmithonwpf.wordpress.com/2007/06/22/overview-of-dependency-properties-in-wpf/
依赖属性内部: http://www.i-programmer.info/programming/wpf-workings/443-inside-dependency-properties-.html
WPF:依赖属性的静态性质: http://dotnetslackers.com/Debugger/re-126399_WPF_The_Static_Nature_of_Dependency_Properties.aspx
为了补充其他答案已经涵盖的内容:
在概念上,依赖属性的核心是一种系统,允许查询根据不同来源的列表获取值,而不是返回单个存储的值。这样做有很多影响,正如其他答案中所列举的那样,但实际上发生的情况是,在获取值时表现出以下行为(当然是极其简化的):
private string _coerced;
private string _animated;
private string _local;
private string _triggered;
private string _styled;
private string _inherited;
private string _default;
public string MyDP
{
get
{
return _coerced ?? _animated ?? _local ?? _triggered ?? _styled ?? _inherited ?? _default;
}
}