13

这个让我难住了。我们有一个自定义 ItemsControl,它使用自定义容器和自定义面板作为其 ItemsHost。现在,面板具有容器渲染所需的一些指标。由于它们是可视树中面板的直接子级,您可能会认为容器的 Parent 属性会返回面板,但事实并非如此!

我还在标准 ListBox 上使用 Snoop 确认了这个确切的事情,所以这不是我们的代码所独有的,而是显然所有 ItemsControls 容器。

现在我知道我可以使用 VisualTreeHelper 来获取可视父级(这是我需要的),但为什么父级不是面板?

如果参数是面板只是可视树的一部分,而父级是为逻辑树保留的,那么父级不是 ItemsControl 吗?

如果容器的参数也是 ItemsControl 的可视化树而不是逻辑树的一部分,那么为什么容器中托管的内容会将容器作为其 Parent 属性返回?

这意味着如果您从数据项遍历逻辑树,您会在容器处停下来,这可以解释为什么我们从容器到面板的绑定没有按预期工作。(我相信绑定是基于逻辑层次结构而不是视觉层次结构,但我必须进行测试才能确定。)

4

2 回答 2

8

我从来没有注意到这一点,这激起了我的好奇心。在 .Net Framework 中寻找线索后,发现 Parent 属性似乎确实是手动设置的:这需要几个步骤,但我发现更改父属性的唯一方法是调用这些方法:

父母做作

如果我分析例如 FrameworkElement.AddLogicalChild 方法,我发现这些方法正在使用它:

FrameworkElement.AddLogicalChild 分析

这确认了父属性应该引用逻辑树。我尝试创建自己的自定义控件:

[ContentProperty("CustomContent")]
public class CustomControl1 : Control
{
    static CustomControl1()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
    }

    public object CustomContent
    {
        get { return GetValue(CustomContentProperty); }
        set { SetValue(CustomContentProperty, value); }
    }

    public static readonly DependencyProperty CustomContentProperty = DependencyProperty.Register("CustomContent", typeof(object), typeof(CustomControl1));
}

使用此模板:

<ControlTemplate TargetType="{x:Type local:CustomControl1}">
     <ContentPresenter ContentSource="CustomContent" />
</ControlTemplate>

我是这样用的:

<WpfApplication1:CustomControl1 Width="50" Height="50">
    <Rectangle Fill="Red" />
</WpfApplication1:CustomControl1>

...这就像这样(就像一个魅力:-)):

自定义控制屏幕截图

...猜猜看...矩形的父级未设置:-)

我现在没有时间继续调查,但是关于 ItemsControl,我想也许 ItemContainerGenerator 不知道它插入 itemsContainers 的逻辑父级,这可以解释为什么在这种情况下没有设置父属性......但是这需要证明...

于 2013-02-20T09:22:25.383 回答
4

FrameworkElement.Parent属性文档说它可能为空,例如在数据模板中创建的项目。在这种情况下,他们建议使用FrameworkElement.TemplatedParent

对于模板,模板的 Parent 最终将为 null。要超越这一点并扩展到实际应用模板的逻辑树,请使用 TemplatedParent。

可能是你的情况?它在类似的情况下帮助了我(Parent如果它是 null 用作TemplateParent后备,我就使用 then)。

是的,答案已经晚了,但它可能会帮助其他与我遇到同样错误的人

于 2018-05-03T16:19:51.883 回答