Question

J'ai un ListBox avec un ItemsPanel

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

Je suis désireux de déplacer le panneau pile le long de l'axe X utilisant un TranslateTransform dans le code derrière.

Le problème est, je ne peux pas trouver le panneau de la pile.

ThumbListBox.FindName("ThumbListStack")

ne renvoie rien. Je veux l'utiliser dans:

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

Comment puis-je obtenir le panneau de la pile pour que je puisse ensuite l'utiliser avec le TranslateTransform

Merci

Était-ce utile?

La solution

Vous pouvez utiliser l'événement pour la Loaded StackPanel qui est dans le 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>

Et puis dans le code derrière

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

Une autre façon est de parcourir l'arborescence visuelle et trouver le StackPanel qui sera le premier enfant du 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;
}

Autres conseils

désolé, je viens de remarquer que j'oublié de sauvegarder le modifier ... Je sais que vous avez déjà accepté une réponse, mais il semble plus d'un hack pour moi. Voici ma mise en œuvre de FindChild, vous pouvez l'utiliser pour l'avenir ou si vous allez faire souvent.

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

Il vérifie tous les enfants et les enfants des enfants comparant le type et ensemble Nom sur le contrôle. Utilisez comme ceci:

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

Essayez la méthode suivante d'extension:

var childStackPanels = FindVisualChildren<StackPanel>(ThumbListBox);

Méthode elle-même:

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:. Vous pouvez vous étendre pour vérifier le nom de contrôle spécifique si la méthode retournerait contrôle unique au lieu de la liste

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top