如何从ItemsControl派生的自定义控件中访问ItemsHost

如何从ItemsControl派生的自定义控件中访问ItemsHost

问题描述:

我正在创建一个名为FooControl的派生自ItemsControl的自定义控件,它在theme \ generic.xaml中定义了相同的默认样式。如何从ItemsControl派生的自定义控件中访问ItemsHost

FooControl的默认样式将ItemsPanel属性设置为另一个名为FooPanel的自定义面板,如下所示(我不认为自定义面板的用法对此问题很重要)。

<Setter Property="ItemsPanel"> 
    <Setter.Value> 
    <ItemsPanelTemplate> 
     <local:FooPanel IsItemsHost="True"/> 
    </ItemsPanelTemplate> 
    </Setter.Value> 
</Setter> 

在我的FooControl后面的代码中,我想访问自动创建的FooPanel实例。通过查看反射器,我发现ItemsControl确实有一个名为ItemsHost的属性,但我无法从FooControl访问它,因为ItemsHost是内部的

有人可能会建议我一个可靠的方法来获取对FooPanel实例的引用吗?

不幸的是,ItemsControl控件没有公开对这个元素的引用(事实上,我有一种感觉,即ItemsControl甚至不能访问它本身)。

使用VisualTreeHelper.GetChild()按照上一篇文章的建议可能会有效,但如果项目控件重新设置的方式导致项目面板进一步向下嵌套,它将会中断。

一个稍微不那么脆弱(但不够完善仍然远)的方式来获得一提的是获得第一个孩子容器的父(假设你的项目控制至少包含一个项目)

Panel itemsPanel; 

if (Items.Count == 0) 
{ 
    itemsPanel = null; 
} 
else 
{ 
    var firstContainer = ItemContainerGenerator.ContainerFromIndex(0); 

    itemsPanel = VisualTreeHelper.GetParent(firstContainer) as Panel; 
} 

注意:这只适用于SL3及以上版本,因为它使用ItemContainerGenerator属性(我相信SL2可能存在解决方法)

您可以使用VisualTreeHelper.GetChild(...)。我相信它应该是ItemsControl子类的第一个或第二个子元素。