我对这些魔法有点不清楚。 据我所知,依赖属性从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));
对Attached属性的AddOwner方法调用是否为实例字段赋值?这是什么时候发生的?价值在哪里?
谢谢!
答案 0 :(得分:3)
WPF中的属性系统非常复杂。 MSDN确实有很多信息,但通常很难找到。 While there are many ways a DependencyProperty
can be set,我不确定您是否需要关注存储值的位置。
对于本地值,您可以假设它存储在DependencyObject
上(同样您不应该关心它存储在何处),但需要注意的是它们不是基于字符串存储的。它确实与DependencyProperty
的实例相关联。这就是您希望将属性添加到属性的原因。如果有人在您的控件上设置TextElement.FontSize
,就像设置您的本地FontSize
属性一样。
就从父级继承属性的值而言,此仅与附加属性一起发生。来自FrameworkPropertyMetadataOptions
的{{3}}:
虽然属性值继承似乎有效 非附加依赖项属性,a的继承行为 通过运行时中的某些元素边界的非附加属性 树未定义。始终使用RegisterAttached来注册属性 您可以在元数据中指定Inherits。
答案 1 :(得分: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;