Visual and Logical tree traversal does not retrieve several levels

405 Views Asked by At

I'm exploring logical and visual trees from the same application without success going deeper through the levels.

My code uses a generic explorer:

private static void ProcessGenericTree(object current, List<FrameworkElement> leaves, Type treeType) 
        {
            if (current is FrameworkElement)
            {
                if (!leaves.Contains(current as FrameworkElement))
                    leaves.Add(current as FrameworkElement);
            }

            DependencyObject dependencyObject = current as DependencyObject;

            if (dependencyObject != null)
            {
                if (treeType.Equals(typeof(VisualTreeHelper)))
                {
                    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
                    {
                        ProcessVisualTree(VisualTreeHelper.GetChild(dependencyObject, i), leaves);
                    }
                }
                else
                {
                    foreach (object child in LogicalTreeHelper.GetChildren(dependencyObject))
                    {
                        ProcessLogicalTree(child, leaves);
                    }
                }
            }
        }

ProcessLogicalTree and ProcessVisualTree simply iterate (doing something before the ProcessGenericTree re-call).

The result looks complete, but when I'm trying to retrieve a TextBlock into a GridViewColumn Header it looks like the item doesn't exist neither in the Logical nor in the Visual leaves list of FrameworkElement.

It seems to be a Visual Element into a Logical Element. In fact adding a watch this TextBlock appears in the Visual Children of my GridView (retrieved as logical, it stands in a Tab Item not selected), but my code isn't unable to get it.

My call is pretty simple:

         ProcessVisualTree(root, _visualElements);
         ProcessLogicalTree(root, _logicalElements);

where root is the MainWindow.

So, how can I explore my tree at its deepest level? Maybe re-iterating through the retrieved FrameworkElement list? I think my ProcessGeneric code already does it.

Update: the WPF Visualizer shows a structure of this kind:

ListView > ScrollViewer > Grid > DockPanel > Grid > ScrollContentPresenter > GridViewHeaderRowPresenter > GridViewColumnHeader > HeaderBorder

The GridViewColumnHeader level contains my TextBlock but the visual tree doesn't.

Update 2: using the recursion starting from the main window with my element visible I'm not able to Find the object with a specified name with this code:

public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject
{
    if (depObj != null)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
            if (child != null && child is T)
            {
                return (T)child;
            }

            T childItem = FindVisualChild<T>(child);
            if (childItem != null) return childItem;
        }
    }
    return null;
}

I'm pretty sure the VisualTreeHelper is not able to retrieve elements inside Header property but the WPF Inspector works correctly.

I wonder if it uses a different approach to traverse the tree (maybe inspecting the Properties like Header too). Suggestions?

0

There are 0 best solutions below