Pregunta

Tengo un cuadro de lista con un elementopanel

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

Quiero mover el panel de pila a lo largo del eje X utilizando una transformación tradicional en código detrás.

El problema es que no puedo encontrar el panel de pila.

ThumbListBox.FindName("ThumbListStack")

No devuelve nada. Quiero usarlo en:

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

¿Cómo obtengo el panel de pila para que pueda usarlo con la transformación?

Gracias

¿Fue útil?

Solución

Puedes usar el Loaded evento para el StackPanel que esta en el 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>

Y luego en código detrás

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

Otra forma es atravesar el árbol visual y encontrar el StackPanel ¿Cuál será el primer hijo del 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;
}

Otros consejos

Lo siento, acabo de notar que olvidé guardar la edición ... Me doy cuenta de que ya ha aceptado una respuesta, pero me parece más un truco. Aquí está mi implementación de Findchild, es posible que desee usarlo para el futuro o si va a hacer esto a menudo.

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

Verifica a todos los niños y los niños de los niños que comparan el tipo y el nombre establecido en el control. Úselo así:

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

Pruebe el método de extensión de siguientes:

var childStackPanels = FindVisualChildren<StackPanel>(ThumbListBox);

Método en sí:

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

PD: Puede extenderlo para verificar el nombre de control específico para que el método devuelva el control único en lugar de la lista.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top