声明的 XAML 列表项何时设置其依赖属性?

When do declared XAML list items have their dependency properties set?

背景

我正在创建自定义 wpf 面板。为了帮助布置子项目,它使用了我称之为 "layouts" 的辅助列表(类似于 Grid.RowDefinitions 或 Grid.ColumnDefinitions)。每个布局都有几个依赖属性,子项使用附加的 属性 来确定它们的放置位置,如下所示。

<Panel>
    <Panel.Layouts>
        <Layout/>
        <Layout Attachment="Right"/>
        <Layout Attachment="Left" Target="0"/>
    </Panel.Layouts>

    <ChildItem Panel.Layout="0"/>
    <ChildItem Panel.Layout="1"/>
    <ChildItem Panel.Layout="2"/>
<Panel/>

显然,事情简化了一点,但长话短说:我需要在 "Arrange" 过程发生之前处理添加的布局。我已经创建了一个自定义集合,我可以在添加项目时看到它们(参见下面的代码),但这些项目只有它们的默认属性。

LayoutCollection: IList
{
    public int IList.Add(object value)
    {
        // When first starting, this line always returns the default value, not the one set in XAML
        Attachment a = (value as Layout).Attachment;

        // Other code happens below...
    }
 }

但是,当我在面板初始化后查看集合时,所有属性都已正确设置。这让我想到了我的问题:

问题

在 XAML 和面板初始化之间的过程中,项目在什么时候被分配了它们的属性,它们是如何分配的?我需要以某种方式连接到它和 运行 一些代码。

我的想法是,WPF 的 Panel 布局系统并不是真正设计为按照您希望的方式进行拦截。

但是有一种机制可以 'sync' 您的自定义 DependencyProperties。问题是在布局过程中什么时候需要这些属性?

如果是在ArrangeOverride期间,则必须设置AffectsArrange。或者在 MeasureOverride 期间 AffectsMeasure。这个还有一些其他的口味,不过我觉得这两个都能满足你的要求。

例如,如果您选择 AffectsArrange 并且您的面板收到 List.Add 的通知,将调用 ArrangeOverride 并且可以在您的排列逻辑中使用新添加的项目。