Every ItemsControl
has its content stored in Panel right ? We can specify the panel to be used in XAML like this:
每个项目控制都有其内容存储在面板中,对吗?我们可以指定在XAML中使用的面板如下:
<ListView Name="LView">
<ListView.ItemsPanel>
<ItemsPanelTemplate >
<StackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
My question is how to get instance of Panel
that is used in the ItemsPanel
property (of type ItemsPanelTemplate
) of the particular ItemsControl
? For example ListView
called LView
from above code sample?
我的问题是如何获得在ItemsPanel属性(类型为ItemsPanelTemplate)中使用的面板实例?例如,ListView从上面的代码示例中调用LView ?
I cannot use Name
property or x:Name
, this must work for any ItemsControl
even those using default ItemsPanel
.
我不能使用Name属性或x:Name,这必须适用于任何ItemsControl,即使是使用默认ItemsPanel的。
In the case its not clear please comment, I think there is very simple solution. If it seems to be complicated that's only because I cannot explain it properly.
对于不清楚的情况,请评论,我认为有很简单的解决办法。如果它看起来很复杂,那只是因为我不能正确地解释它。
3 个解决方案
#1
15
It's a little tricky since you don't know the name of the Panel so you can't use FindName etc. This will work for most cases where an ItemsPresenter
is present
这有点棘手,因为您不知道面板的名称,所以不能使用FindName等。这对于存在ItemsPresenter的大多数情况都适用
private Panel GetItemsPanel(DependencyObject itemsControl)
{
ItemsPresenter itemsPresenter = GetVisualChild<ItemsPresenter>(itemsControl);
Panel itemsPanel = VisualTreeHelper.GetChild(itemsPresenter, 0) as Panel;
return itemsPanel;
}
An implementation of GetVisualChild
的一个实现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;
}
However, the ItemsPanel isn't always used. See this answer by Ian Griffiths for a great explanation.
然而,ItemsPanel并不总是被使用。请参阅伊恩·格里菲思的回答,以获得一个很好的解释。
#2
3
I can't provide you with working code, but have a look at VisualTreeHelper class. With the VisualTreeHelper class you can traverse the visual tree down to your template and panel.
我不能为您提供工作代码,但请查看VisualTreeHelper类。使用VisualTreeHelper类,您可以遍历可视化树到模板和面板。
#3
2
protected Panel ItemsHost {
get {
return (Panel) typeof (MultiSelector).InvokeMember("ItemsHost",
BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance,
null, this, null);
}
}
This works like a charm in my ItemsControl
! That said, it does have IsItemsHost="True"
on the Panel
inside, but might even work without it.
这在我的物品控制中很有用!也就是说,它内部的面板上确实有IsItemsHost=“True”,但如果没有它,它甚至可以工作。
Trick is from this thread: Can I access ItemsHost of ItemsControl using reflection?
技巧来自这个线程:我可以使用反射访问ItemsControl的ItemsHost吗?
#1
15
It's a little tricky since you don't know the name of the Panel so you can't use FindName etc. This will work for most cases where an ItemsPresenter
is present
这有点棘手,因为您不知道面板的名称,所以不能使用FindName等。这对于存在ItemsPresenter的大多数情况都适用
private Panel GetItemsPanel(DependencyObject itemsControl)
{
ItemsPresenter itemsPresenter = GetVisualChild<ItemsPresenter>(itemsControl);
Panel itemsPanel = VisualTreeHelper.GetChild(itemsPresenter, 0) as Panel;
return itemsPanel;
}
An implementation of GetVisualChild
的一个实现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;
}
However, the ItemsPanel isn't always used. See this answer by Ian Griffiths for a great explanation.
然而,ItemsPanel并不总是被使用。请参阅伊恩·格里菲思的回答,以获得一个很好的解释。
#2
3
I can't provide you with working code, but have a look at VisualTreeHelper class. With the VisualTreeHelper class you can traverse the visual tree down to your template and panel.
我不能为您提供工作代码,但请查看VisualTreeHelper类。使用VisualTreeHelper类,您可以遍历可视化树到模板和面板。
#3
2
protected Panel ItemsHost {
get {
return (Panel) typeof (MultiSelector).InvokeMember("ItemsHost",
BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance,
null, this, null);
}
}
This works like a charm in my ItemsControl
! That said, it does have IsItemsHost="True"
on the Panel
inside, but might even work without it.
这在我的物品控制中很有用!也就是说,它内部的面板上确实有IsItemsHost=“True”,但如果没有它,它甚至可以工作。
Trick is from this thread: Can I access ItemsHost of ItemsControl using reflection?
技巧来自这个线程:我可以使用反射访问ItemsControl的ItemsHost吗?