如何在代码中获取ListBox ItemsPanel

Ben*_*Ben 14 .net c# wpf code-behind itemspanel

我有一个带有ItemsPanel的ListBox

<Setter Property="ItemsPanel">
    <Setter.Value>
        <ItemsPanelTemplate>
             <StackPanel x:Name="ThumbListStack" Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </Setter.Value>
</Setter>
Run Code Online (Sandbox Code Playgroud)

我想在后面的代码中使用TranslateTransform沿X轴移动堆栈面板.

问题是,我找不到Stack Panel.

ThumbListBox.FindName("ThumbListStack")
Run Code Online (Sandbox Code Playgroud)

什么都不返回 我想用它:

Storyboard.SetTarget(x, ThumbListBox.FindName("ThumbListStack"))
Run Code Online (Sandbox Code Playgroud)

如何获取堆栈面板,以便我可以将其与TranslateTransform一起使用

谢谢

Fre*_*lad 23

您可以使用Loaded该事件StackPanel是在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>
Run Code Online (Sandbox Code Playgroud)

然后在代码背后

private StackPanel m_itemsPanelStackPanel;
private void StackPanel_Loaded(object sender, RoutedEventArgs e)
{
    m_itemsPanelStackPanel = sender as StackPanel;
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是遍历可视树并找到StackPanel哪个将成为第一个孩子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;
}
Run Code Online (Sandbox Code Playgroud)

  • 最好将GetVisualChild()重命名为GetFirstVisualChild() (2认同)