为什么ItemsControl的容器的Parent属性返回null,而不是它所在的Panel?

问题描述 投票:12回答:2

这个让我难过。我们有一个自定义ItemsControl,它同时使用自定义容器和自定义面板作为ItemsHost。现在,面板具有一些容器渲染所需的度量标准。由于它们是面板在视觉树中的直接子代,因此您认为容器的Parent属性将返回面板,但事实并非如此!

[我也已经在标准ListBox上使用Snoop确认了这件事,因此这并非我们的代码独有,但显然是ItemsControls的所有容器。

现在我知道我可以使用VisualTreeHelper来获取可视父对象(这是我所需要的,但是为什么父not将成为面板?

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

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

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

wpf parent itemscontrol visualtreehelper
2个回答
7
投票

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

“父母感情”

[例如,如果我分析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>

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

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9vUjgzNS5wbmcifQ==” alt =“自定义控件屏幕标题”>

...,然后猜怎么着... 未设置矩形的父对象:-)

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


3
投票

FrameworkElement.Parent属性documentation表示它可能为null,例如用于在datatemplates中创建的项目。在这种情况下,他们建议使用FrameworkElement.TemplatedParent

对于模板,模板的父级最终将为null。至越过这一点,并延伸到逻辑树中模板已实际应用,请使用TemplatedParent。

可能是您的情况吗?它在类似的情况下对我有帮助(我使用Parent,如果它为null,则使用TemplateParent作为备用)。

是,答案晚了,但可能会帮助其他偶然发现与我相同的错误的人

© www.soinside.com 2019 - 2024. All rights reserved.