VisualTreeHelper not finding children of DependencyObject, How can I reliably find objects?

青春壹個敷衍的年華 提交于 2019-12-10 12:09:14

问题


I have a UserControl called ZoneContainer. This has a property that which contains a ListBox containing a number of ListItems. Each ListItem contains a DockPanel.

I'm trying to use a the following code to find the children that exist inside ZoneContainer but childrenCount is 0 every time.

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

int childrenCount = VisualTreeHelper.GetChildrenCount(parent);

Is there another way to find a specific child object inside a list of objects? Ultimately I'm trying to find the DockPanel, but it's not finding any children even though I know they're in the object.


回答1:


The basic problem here is that not all childs are part of the VisualTree
You can find more information about this problem in this articel from Josh Smith

here are my extension to get all Childs

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



回答2:


This is the function I've got lurking in my library. I've never had any trouble with it, but it does have a GetChildrenCount() call in it so if that's not working for you you may have a bigger problem.

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

Usage: x = FindVisualChild(Of DockPanel)(ParentObject)

Yes, I know it's VB. It's about time one of you C# guys had to convert code for once! :)




回答3:


I resolved this issue by querying the objects rather than crawling the visual tree.

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


来源:https://stackoverflow.com/questions/13248013/visualtreehelper-not-finding-children-of-dependencyobject-how-can-i-reliably-fi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!