对于Attached Properties如何将其值传递给父元素或子元素,我有点神秘。 TextElement.FontFamily
导致子元素继承分配给该属性的值(看似下游的操作,父子对象)。 Grid.Column
导致父项在特定位置显示该子项(看似上游操作,子项到父项)。 Attached Property值如何知道要么向上还是向下流动?我的这个概念是不正确的,还是有一个缺失的部分会将所有这些都放到透视中?
<StackPanel TextElement.FontFamily="Wingdings">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="1" Content="My Button"/>
</Grid>
</StackPanel>
答案 0 :(得分:41)
此处有两个概念:依赖项属性和附加依赖项属性。 “附加属性”是依赖属性,因此支持依赖property value inheritance。
关于基本依赖属性,一个非常粗略的陈述是它们基本上从wpf(逻辑/可视)树中的父元素继承它们的值。如果依赖属性(已附加或未附加)的metadata设置为FrameworkPropertyMetadataOptions。继承标志,则依赖属性(附加或不附加)会继承其值,并且在很多情况下都是如此。< / p>
附加属性是可以通过DependencyObject.SetValue方法在任何wpf对象上设置的属性(基本上,至少一个DependencyObject)。此机制的目的是“附加”父对象所需的其他对象信息,而不是子对象本身。例如,Grid.Row是Grid所需的附加属性,用于将项目放置在其渲染区域中。
依赖属性由wpf对象系统自动“向下”继承。
在特定对象的代码中,显式地“向上”检查附加属性。对于Grid,在确定放置项目的位置时,它会检查每个包含项目的Grid.Row和Grid.Column附加属性的值。
通常也是创建自定义附加属性的技术,这些属性以某种方式修改它们所附加的对象(例如,Drag'n'Drop functionality via attached properties)。
作为补充说明,继承附加属性的一个很好的例子是TextElement.FontFamily。 Grid.Row和Grid.Column属性没有设置Inherits标志。
TextElement.FontFamily,来自Reflector:
FontFamilyProperty = DependencyProperty.RegisterAttached("FontFamily", typeof(FontFamily), typeof(TextElement), new FrameworkPropertyMetadata(SystemFonts.MessageFontFamily, FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(TextElement.IsValidFontFamily));
Grid.Row,来自Reflector:
RowProperty = DependencyProperty.RegisterAttached("Row", typeof(int), typeof(Grid), new FrameworkPropertyMetadata(0, new PropertyChangedCallback(Grid.OnCellAttachedPropertyChanged)), new ValidateValueCallback(Grid.IsIntValueNotNegative));
答案 1 :(得分:3)
来自MSDN:
虽然附加属性可以在任何对象上设置,但这并不意味着设置属性会产生有形结果,或者该值将被其他对象使用。通常,附加属性旨在使来自各种可能的类层次结构或逻辑关系的对象都可以向定义附加属性的类型报告公共信息。定义附加属性的类型通常遵循以下模型之一:
定义附加的类型 财产的设计使它可以 是元素的父元素 这将设置附加的值 属性。然后该类型迭代它 子对象通过内部逻辑 针对某些对象树结构, 获得价值,并对这些价值采取行动 以某种方式的价值观。
定义附加的类型 财产将用作孩子 各种可能的元素 父元素和内容模型。
定义附加的类型 property代表一项服务。其他 类型设置附加的值 属性。然后,当元素那个 设置属性在中进行评估 服务的背景,附上 财产价值是通过 服务类的内部逻辑。
父母定义的附加财产的示例
WPF定义附加属性的最典型场景是父元素支持子元素集合时,还实现了为每个子元素单独报告行为细节的行为。
DockPanel定义了DockPanel.Dock附加属性,而DockPanel将类级代码作为其渲染逻辑的一部分(具体来说,是MeasureOverride和ArrangeOverride)。 DockPanel实例将始终检查其任何直接子元素是否为DockPanel.Dock设置了值。如果是,则这些值成为应用于该特定子元素的呈现逻辑的输入。嵌套的DockPanel实例各自处理它们自己的直接子元素集合,但该行为是特定于实现的DockPanel如何处理DockPanel.Dock值。从理论上讲,附加属性可能会影响直接父级之外的元素。如果在没有DockPanel父元素的元素上设置DockPanel.Dock附加属性,则不会引发错误或异常。这只是意味着设置了一个全局属性值,但它没有可以使用该信息的当前DockPanel父级。
答案 2 :(得分:0)
简单来说,这就是我理解的方式(如果我错了,请纠正我。)
对象(A)实现将附加到另一个对象(B)的属性(对象B甚至不知道这个“可附加”属性的存在)。对象B需要从DependencyObject继承。
对象A还实现了一个静态方法来检查它在其他对象中的“可附加”属性,A.GetAttachedProperty(B)。
如果B具有来自A的附加属性,则A.GetAttachedProperty将读取并返回其值。否则A将尝试读取它,并返回null,因为它不存在。