Search code examples
c#.netwpfcode-behinditemspanel

How to get ListBox ItemsPanel in code behind


I have a ListBox with an ItemsPanel

<Setter Property="ItemsPanel">
    <Setter.Value>
        <ItemsPanelTemplate>
             <StackPanel x:Name="ThumbListStack" Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </Setter.Value>
</Setter>

I am wanting to move the Stack Panel along the X-axis using a TranslateTransform in code behind.

Problem is, I can't find the Stack Panel.

ThumbListBox.FindName("ThumbListStack")

Returns nothing. I want to use it in:

Storyboard.SetTarget(x, ThumbListBox.FindName("ThumbListStack"))

How do I get the Stack Panel so I can then use it with the TranslateTransform

Thanks


Solution

  • 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;
    }