How to get instance of Panel that holds content of ItemsControl?
Solution 1
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
private Panel GetItemsPanel(DependencyObject itemsControl)
{
ItemsPresenter itemsPresenter = GetVisualChild<ItemsPresenter>(itemsControl);
Panel itemsPanel = VisualTreeHelper.GetChild(itemsPresenter, 0) as Panel;
return itemsPanel;
}
An implementation of 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.
Solution 2
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.
Solution 3
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.
Trick is from this thread: Can I access ItemsHost of ItemsControl using reflection?
![Rasto](https://i.stack.imgur.com/ok824.jpg?s=256&g=1)
Rasto
Entrepreneur, UX consultant, full-stack developer with strongest competency in Swift & iOS. Can get die-hard about top-notch UX and code quality. Diving deeper into React and getting excited about GraphQL. My pro history chapters are written in C#, Objective-C, Java, JS, TS, Flow, even Haskel, Prolog & Pascal. Sports and outdoor enthusiast. Love exploring cultures around the world. Found in mountains in the winter and at seaside during summer. Amater photographer. Always happy to learn and share what I learned e.g. externally giving lectures at my alma mater.
Updated on June 07, 2022Comments
-
Rasto about 2 years
Every
ItemsControl
has its content stored in Panel right ? We can specify the panel to be used in XAML like this:<ListView Name="LView"> <ListView.ItemsPanel> <ItemsPanelTemplate > <StackPanel/> </ItemsPanelTemplate> </ListView.ItemsPanel> </ListView>
My question is how to get instance of
Panel
that is used in theItemsPanel
property (of typeItemsPanelTemplate
) of the particularItemsControl
? For exampleListView
calledLView
from above code sample?I cannot use
Name
property orx:Name
, this must work for anyItemsControl
even those using defaultItemsPanel
.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.