Frage

Ich habe eine Listbox mit einem ElementSpanel

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

Ich möchte das Stapelfeld entlang der X-Achse unter Verwendung einer Translatetransform im Code dahinter verschieben.

Problem ist, ich kann das Stapelpanel nicht finden.

ThumbListBox.FindName("ThumbListStack")

Gibt nichts zurück. Ich möchte es verwenden in:

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

Wie bekomme ich das Stack -Panel, damit ich sie dann mit der Translatetransform verwenden kann

Vielen Dank

War es hilfreich?

Lösung

Du kannst den ... benutzen Loaded Ereignis für die StackPanel das ist in der 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>

Und dann im Code dahinter

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

Eine andere Möglichkeit besteht darin, den visuellen Baum zu durchqueren und den zu finden StackPanel Welches wird das erste Kind der 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;
}

Andere Tipps

Entschuldigung, ich habe gerade bemerkt, dass ich vergessen habe, die Bearbeitung zu retten ... Mir ist klar, dass Sie bereits eine Antwort angenommen haben, aber es scheint mir eher ein Hack. Hier ist meine Implementierung von FindChild. Vielleicht möchten Sie es für die Zukunft verwenden oder wenn Sie dies oft tun.

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

Es überprüft alle Kinder und Kinder der Kinder, die den Typ und den Namen der Kontrolle vergleichen. Verwenden Sie es so:

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

Versuchen Sie es mit der folgenden Erweiterungsmethode aus:

var childStackPanels = FindVisualChildren<StackPanel>(ThumbListBox);

Methode selbst:

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: Sie können es selbst erweitern, um nach einem bestimmten Steuernamen zu überprüfen, sodass die Methode eine einzelne Steuerung anstelle der Liste zurückgibt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top