附加属性在WPF中究竟是如何工作的?

附加属性在WPF中究竟是如何工作的?,wpf,xaml,attached-properties,Wpf,Xaml,Attached Properties,对于附加属性如何将其值传递给父元素或子元素,我有点困惑TextElement.FontFamily使子元素继承分配给该属性的值(一个看似下游的操作,从父到子)Grid.Column使父项在特定位置显示该子项(一种看似上游的操作,从子项到父项)。附着的属性值如何知道向上或向下流动?我对这一点的理解是错误的,还是缺少了一块可以让所有这些都进入正确的角度 <StackPanel TextElement.FontFamily="Wingdings"> <Grid>

对于附加属性如何将其值传递给父元素或子元素,我有点困惑
TextElement.FontFamily
使子元素继承分配给该属性的值(一个看似下游的操作,从父到子)
Grid.Column
使父项在特定位置显示该子项(一种看似上游的操作,从子项到父项)。附着的属性值如何知道向上或向下流动?我对这一点的理解是错误的,还是缺少了一块可以让所有这些都进入正确的角度

<StackPanel TextElement.FontFamily="Wingdings">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Button Grid.Column="1" Content="My Button"/>
    </Grid>
</StackPanel>

来自:

尽管附着的属性可以在任何对象上设置,但这并不自动意味着设置该属性将产生有形的结果,或者该值将被其他对象使用。通常,附加属性旨在使来自各种可能的类层次结构或逻辑关系的对象都可以向定义附加属性的类型报告公共信息。定义附着特性的类型通常遵循以下模型之一:

  • 定义所附着对象的类型 属性的设计使其能够 是元素的父元素 这将为附加的属性设置值 财产。然后,该类型迭代其 通过内部逻辑的子对象 针对某些对象树结构, 获取值,并根据这些值执行操作 在某种程度上,价值观

  • 定义所附着对象的类型 属性将用作子级 元素,用于各种可能的 父元素和内容模型

  • 定义所附着对象的类型 属性表示服务。其他 类型为附着的对象设置值 财产。然后,当元素 设置在中计算属性的值 服务的上下文,附加的 属性值通过以下方式获得: 服务类的内部逻辑

父级定义的附加属性的示例

WPF定义附加属性的最典型场景是,父元素支持子元素集合,并且还实现了一种行为,在这种行为中,每个子元素分别报告行为的细节


DockPanel定义DockPanel.Dock attached属性,DockPanel的呈现逻辑中包含类级代码(特别是MeasureOverride和ArrangeOverride)。DockPanel实例将始终检查其任何直接子元素是否为DockPanel.Dock设置了值。如果是,这些值将成为应用于该特定子元素的渲染逻辑的输入。嵌套的DockPanel实例每个都处理它们自己的直接子元素集合,但该行为是特定于DockPanel处理DockPanel.Dock值的实现。从理论上讲,可以附加影响直接父元素以外元素的属性。如果在没有DockPanel父元素对其进行操作的元素上设置了DockPanel.Dock attached属性,则不会引发错误或异常。这仅仅意味着设置了一个全局属性值,但它没有可以使用该信息的当前DockPanel父级。

这里有两个概念:依赖属性附加的依赖属性。“附加属性”是依赖性属性,因此支持依赖性

关于基本依赖属性,一个非常粗略的说法是它们基本上从wpf(逻辑/可视)树中的父元素继承它们的值。如果依赖项属性设置了。Inherit标志,则依赖项属性(是否附加)将继承其值“down”,在许多情况下也是如此

附加属性是可以通过方法在任何wpf对象(基本上,至少是DependencyObject)上设置的属性。此机制的目的是将父对象所需的信息“附加”到其他对象,而不是子对象本身。例如,是栅格在其渲染区域内放置项目所需的附着特性

依赖项属性由wpf对象系统自动“向下”继承

附加属性在特定对象的代码中明确地“向上”检查。对于Grid,在确定放置其项的位置时,它会检查每个包含项上的Grid.Row和Grid.Column附加属性的值

创建自定义附着特性(以某种方式修改附着到的对象(例如,对象)通常也是一种技术

另请注意,继承附着属性的一个很好的示例是。Grid.Row和Grid.Column属性未设置继承标志

TextElement.FontFamily,来自反射器:

FontFamilyProperty=DependencyProperty.RegisterAttached(“FontFamily”、typeof(FontFamily)、typeof(TextElement)、new FrameworkPropertyMetadata(SystemFonts.MessageFontFamily、FrameworkPropertyMetadata Options.Inherits | FrameworkPropertyMetadata Options.AffectsRender | FrameworkPropertyMetadata Options.AffectsMeasure)、new ValidateValidateValue回调(TextElement.IsValidFontFamily));
网格.行,来自反射器:

RowProperty=DependencyProperty.RegisterAttached(“行”、typeof(int)、typeof(Grid)、new FrameworkPropertyMetadata(0、new PropertyChangedCallback(Grid.OnCellAttachedPropertyChanged))、new ValidateValueCallback(Grid.IsIntValueNotNegative));

简单地说,我就是这样理解的(如果我错了,请纠正我)

对象(A)实现一个将附加到另一个对象(B)的属性(对象B甚至不知道这个“可附加”属性的存在)。对象B需要从DependencyObject继承

对象A还实现了一个静态方法来检查