VisualTreeHelper не находит дочерние объекты DependencyObject. Как я могу надежно находить объекты?

У меня есть UserControl с именем ZoneContainer. У этого есть свойство, которое содержит ListBox, содержащее количество ListItem. Каждый ListItem содержит DockPanel.

Я пытаюсь использовать следующий код, чтобы найти дочерние элементы, которые существуют внутри ZoneContainer, но childrenCount каждый раз равен 0.

var parent = this as DependencyObject; // I can see that this is populated.

int childrenCount = VisualTreeHelper.GetChildrenCount(parent);

Есть ли другой способ найти конкретный дочерний объект в списке объектов? В конечном итоге я пытаюсь найти DockPanel, но он не находит дочерних элементов, хотя я знаю, что они находятся в объекте.


person DaveDev    schedule 06.11.2012    source источник
comment
Вы вызываете это в конструкторе ZoneContainer?   -  person Clemens    schedule 06.11.2012
comment
@ Клеменс, да, я ... и я думаю, что понимаю, к чему ведет ваш вопрос. Объекты еще не созданы?   -  person DaveDev    schedule 06.11.2012
comment
Да, попробуйте сделать это в Loaded. обработчик события.   -  person Clemens    schedule 06.11.2012


Ответы (3)


Основная проблема заключается в том, что не все дочерние элементы являются частью VisualTree
Дополнительную информацию об этой проблеме можно найти в этом статья от Джоша Смита

вот мое расширение, чтобы получить всех детей

    public static IEnumerable<DependencyObject> getChilds(this DependencyObject parent)
    {
        if (parent == null) yield break;

        //use the logical tree for content / framework elements
        foreach (object obj in LogicalTreeHelper.GetChildren(parent))
        {
            var depObj = obj as DependencyObject;
            if (depObj != null)
                yield return depObj;
        }

        //use the visual tree for Visual / Visual3D elements
        if (parent is Visual || parent is Visual3D)
        {
            int count = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < count; i++)
            {
                yield return VisualTreeHelper.GetChild(parent, i);
            }
        }
    }
person WiiMaxx    schedule 02.09.2014

Это функция, которая притаилась в моей библиотеке. У меня никогда не было проблем с этим, но в нем есть вызов GetChildrenCount(), поэтому, если это не работает для вас, у вас может быть более серьезная проблема.

Public Shared Function FindVisualChild(Of T As DependencyObject)(ByVal element As DependencyObject) As T
    If element Is Nothing Then
        Return Nothing
    ElseIf TypeOf (element) Is T Then
        Return element
    Else
        Dim count = VisualTreeHelper.GetChildrenCount(element)
        For index As Integer = 0 To count - 1
            Dim child As DependencyObject = VisualTreeHelper.GetChild(element, index)
            If TypeOf (child) Is T Then
                Return child
            Else
                Dim grandchild As T = FindVisualChild(Of T)(child)
                If grandchild IsNot Nothing Then Return grandchild
            End If
        Next
    End If

    Return Nothing
End Function

Использование: x = FindVisualChild (DockPanel) (ParentObject)

Да, я знаю, что это ВБ. Пришло время одному из вас, ребята, C#, преобразовать код в кои-то веки! :)

person PaulMolloy    schedule 06.11.2012

Я решил эту проблему, запрашивая объекты, а не сканируя визуальное дерево.

var header = container.ListBox.Items.Cast<ListBoxItem>()
    .Select(item => (MyType) item.Content)
    .FirstOrDefault(myType => myType.dpHeader.Name == "whatever").dpHeader;
person DaveDev    schedule 26.11.2012