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 the ItemsPanel
property (of type ItemsPanelTemplate
) of the particular ItemsControl
? For example ListView
called LView
from above code sample?
I cannot use Name
property or x:Name
, this must work for any ItemsControl
even those using default 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.
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.