How to get ListBox ItemsPanel in code behind How to get ListBox ItemsPanel in code behind wpf wpf

How to get ListBox ItemsPanel in code behind


You can use the Loaded event for the StackPanel that is in the ItemsPanelTemplate

<Grid>    <Grid.Resources>        <Style TargetType="ListBox">            <Setter Property="ItemsPanel">                <Setter.Value>                    <ItemsPanelTemplate>                        <StackPanel x:Name="ThumbListStack" Orientation="Horizontal"                                    Loaded="StackPanel_Loaded" />                    </ItemsPanelTemplate>                </Setter.Value>            </Setter>        </Style>    </Grid.Resources>    <ListBox /></Grid>

And then in code behind

private StackPanel m_itemsPanelStackPanel;private void StackPanel_Loaded(object sender, RoutedEventArgs e){    m_itemsPanelStackPanel = sender as StackPanel;}

Another way is to traverse the Visual Tree and find the StackPanel which will be the first child of the ItemsPresenter.

public void SomeMethod(){    ItemsPresenter itemsPresenter = GetVisualChild<ItemsPresenter>(listBox);    StackPanel itemsPanelStackPanel = GetVisualChild<StackPanel>(itemsPresenter);}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;}


sorry I just noticed I forgot to save the edit...I realize you've already accepted an answer, but it seems more of a hack to me. Here's my implementation of FindChild, you might want to use it for the future or if you're going to be doing this often.

public static T FindChild<T>(this FrameworkElement obj, string name){    DependencyObject dep = obj as DependencyObject;    T ret = default(T);    if (dep != null)    {        int childcount = VisualTreeHelper.GetChildrenCount(dep);        for (int i = 0; i < childcount; i++)        {            DependencyObject childDep = VisualTreeHelper.GetChild(dep, i);            FrameworkElement child = childDep as FrameworkElement;            if (child.GetType() == typeof(T) && child.Name == name)            {                ret = (T)Convert.ChangeType(child, typeof(T));                break;            }            ret = child.FindChild<T>(name);            if (ret != null)                break;        }    }    return ret;}

It checks all the children and the children's children comparing the type and Name set on the control. Use it like this:

StackPanel ipanel = ThumbListBox.FindChild<StackPanel>("ThumbListStack");if(ipanel == null)    MessageBox.Show("couldn't find anything");else    MessageBox.Show("Aha! Found: " ipanel.Name);


Try out following extension method:

var childStackPanels = FindVisualChildren<StackPanel>(ThumbListBox);

Method itself:

public static IEnumerable<T> FindVisualChildren<T>(this DependencyObject depObj) where T : DependencyObject{    if (depObj != null)    {        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)        {            DependencyObject child = VisualTreeHelper.GetChild(depObj, i);            var typedChild = child as T;            if (typedChild != null)            {                yield return typedChild;            }                foreach (T childOfChild in FindVisualChildren<T>(child))            {                yield return childOfChild;            }        }    }}

PS: You can yourself extend it to check for specific control name so method would return single control instead of list.