Как перебрать множество пользовательских объектов управления в WPF? - PullRequest
1 голос
/ 05 января 2010

В окне моего приложения WPF у меня есть ряд объектов, взятых из пользовательского элемента управления:

...
<MyNamespace:MyCustControl x:Name="x4y3" />
<MyNamespace:MyCustControl x:Name="x4y4" />
<MyNamespace:MyCustControl x:Name="x4y5" />
<MyNamespace:MyCustControl x:Name="x4y6" />
<MyNamespace:MyCustControl x:Name="x4y7" />
...

В своем коде я могу легко ссылаться на каждого из них по имени:

x1y1.IsSelected = true;

Как, в моем коде, я мог бы перебрать весь их набор в цикле?

foreach (... in ???)
{
 ....

}

Ответы [ 2 ]

3 голосов
/ 05 января 2010

Вы можете использовать VisualTreeHelper или LogicalTreeHelper для сканирования всего содержимого вашего окна или страницы и определения местоположения определенных элементов управления (возможно, путем проверки, если их тип MyCustControl

private IEnumerable<MyCustControl> FindMyCustControl(DependencyObject root)
{
    int count = VisualTreeHelper.GetChildrenCount(root);
    for (int i = 0; i < count; ++i)
    {
        DependencyObject child = VisualTreeHelper.GetChild(root, i);
        if (child is MyCustControl)
        {
            yield return (MyCustControl)child;
        }
        else
        {
            foreach (MyCustControl found in FindMyCustControl(child))
            {
                yield return found;
            }
        }
    }
}
0 голосов
/ 24 июля 2013

Отличное решение для тех, кто хочет использовать его универсальную версию - может помочь небольшое изменение, как показано ниже:

public static class ControlFinder<T>
{
    public static IEnumerable<T> FindControl(DependencyObject root)
    {
        int count = VisualTreeHelper.GetChildrenCount(root);
        for (int i = 0; i < count; ++i)
        {
            dynamic child = VisualTreeHelper.GetChild(root, i);
            if (child is T)
            {
                yield return (T)child;
            }
            else
            {
                foreach (T found in FindControl(child))
                {
                    yield return found;
                }
            }
        }
    }
}

Может вызываться:

IEnumerable<MyType> mytypes = ControlFinder<MyType>.FindControl(root);
...