6

我对所有这些魔法有点不清楚。据我了解,依赖属性是从 DependencyObject 继承的,因此会存储值:

  • 如果分配了值,则在实例本身中(在本地字典中)
  • 如果未指定值,则从指向父元素的链接中获取。

    protected object GetValue(string propertyName)
    {
       if (LocalValues.ContainsKey(propertyName))
       {
          return LocalValues[propertyName];
       }
       return Parent.GetValue(propertyName);
    }
    

    我在这方面是正确的吗?

我也不明白附加属性的值存储在哪里?

Control.FontSizeProperty = TextElement.FontSizeProperty.AddOwner(
typeof(Control), new FrameworkPropertyMetadata(SystemFonts.MessageFontSize,
FrameworkPropertyMetadataOptions.Inherits));

附加属性上的 AddOwner 方法调用是否将值分配给实例字段?这种情况什么时候发生,价值又去哪儿了?

谢谢!

4

2 回答 2

3

依赖属性的值存储在我们应用属性值的对象(派生自 DependencyObject)中。

让我们以您的 TextElement.FontSizeProperty 附加属性为例:

<StackPanel TextElement.FontSize="20" ... >
  ...
</StackPanel>

XAML 解析器将其转换为以下内容:

...
TextElement.SetFontSize(stackPanel, 20);
...

这是内部:

public static void SetFontSize(DependencyObject element, double value)
{
  element.SetValue(TextElement.FontSizeProperty, value);
}

因此,在 stackPanel 对象上设置 TextElement.FontSize 与调用相同

stackPanel.SetValue(TextElement.FontSizeProperty, value)

SetValue() 是 DependencyObject 类中定义的方法。在方法内部发生了许多复杂的事情,但最终依赖属性的有效值被包装在一个名为 EffectiveValueEntry 的结构中,并存储在 DependencyObject 内的以下实例字段中:

private EffectiveValueEntry[] _effectiveValues;
于 2013-12-23T15:50:46.197 回答
2

WPF 中的属性系统非常复杂。MSDN确实有很多资料,但往往很难找到。虽然有很多方法DependencyProperty可以设置a ,但我不确定您是否需要关心值的存储位置。

对于本地值,您可以假设它存储在DependencyObject(同样您不应该关心它的存储位置),但需要注意的是它们不是基于字符串存储的。它确实与DependencyProperty. 这就是为什么您要为该属性添加所有者的原因。如果有人设置TextElement.FontSize您的控件,这就像设置您的本地FontSize属性一样。

至于从父级继承属性的值,这只发生在附加属性上。从MSDNFrameworkPropertyMetadataOptions条目:

尽管属性值继承似乎适用于非附加依赖属性,但未定义通过运行时树中某些元素边界的非附加属性的继承行为。始终使用 RegisterAttached 来注册您在元数据中指定 Inherits 的属性。

于 2013-08-12T15:25:40.937 回答