如何获取包含 ItemsControl 内容的 Panel 实例?
Posted
技术标签:
【中文标题】如何获取包含 ItemsControl 内容的 Panel 实例?【英文标题】:How to get instance of Panel that holds content of ItemsControl? 【发布时间】:2011-06-12 07:03:40 【问题描述】:每个ItemsControl
都将其内容存储在 Panel 中,对吗?我们可以像这样指定要在 XAML 中使用的面板:
<ListView Name="LView">
<ListView.ItemsPanel>
<ItemsPanelTemplate >
<StackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
我的问题是如何获取在特定 ItemsControl
的 ItemsPanel
属性(类型为 ItemsPanelTemplate
)中使用的 Panel
的实例?例如上面的代码示例中的ListView
调用LView
?
我不能使用Name
属性或x:Name
,这必须适用于任何ItemsControl
,即使是使用默认ItemsPanel
的那些。
如果不清楚请发表评论,我认为有非常简单的解决方案。如果它看起来很复杂,那只是因为我无法正确解释它。
【问题讨论】:
您想从哪里获取该实例?是来自ItemsControl
还是来自其中的某个项目模板?
完全来自ItemsPanelTemplate
。我绝对不想从项目模板中获取它。
我是否正确理解了您的问题,还是您正在寻找其他内容?
@Meleak:在pivotnig 的回答之后,我能够找到一些解决方案——我所需要的只是有一个VisualTreeHelper 类。我的代码看起来与您提供的非常相似,我不确定差异 - 我不确定我的代码是否总是有效(可能存在一些我不知道的泄漏......)。一段时间后我会接受其中一个答案。
【参考方案1】:
这有点棘手,因为您不知道面板的名称,因此您不能使用 FindName 等。这适用于存在 ItemsPresenter
的大多数情况
private Panel GetItemsPanel(DependencyObject itemsControl)
ItemsPresenter itemsPresenter = GetVisualChild<ItemsPresenter>(itemsControl);
Panel itemsPanel = VisualTreeHelper.GetChild(itemsPresenter, 0) as Panel;
return itemsPanel;
GetVisualChild 的实现
private static T GetVisualChild<T>(DependencyObject parent) where T : Visual
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T;
if (child == null)
child = GetVisualChild<T>(v);
if (child != null)
break;
return child;
但是,并不总是使用 ItemsPanel。请参阅 Ian Griffiths 的 this answer 以获得很好的解释。
【讨论】:
【参考方案2】:我无法为您提供工作代码,但请看一下 VisualTreeHelper class。 使用VisualTreeHelper 类,您可以遍历可视化树到您的模板和面板。
【讨论】:
【参考方案3】:protected Panel ItemsHost
get
return (Panel) typeof (MultiSelector).InvokeMember("ItemsHost",
BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance,
null, this, null);
这在我的ItemsControl
中就像一个魅力!也就是说,它内部的Panel
上确实有IsItemsHost="True"
,但即使没有它也可以工作。
技巧来自这个帖子:Can I access ItemsHost of ItemsControl using reflection?
【讨论】:
【参考方案4】: private object FindItemControl(ItemsControl itemsControl, string controlName, object item)
ContentPresenter container = itemsControl.ItemContainerGenerator.ContainerFromItem(item) as ContentPresenter;
container.ApplyTemplate();
return container.ContentTemplate.FindName(controlName, container);
【讨论】:
以上是关于如何获取包含 ItemsControl 内容的 Panel 实例?的主要内容,如果未能解决你的问题,请参考以下文章
某些项目未通过 ItemsSource 显示在 ItemsControl 中
如何使用 DataTrigger 更改 ItemsControl 中的 ItemsPanel?