0

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?

Francesco De Lisi
  • 1,493
  • 8
  • 20
  • I wonder if this is because the `Header` property is not a `DependencyObject` its is of type `object` so the `Header` itself won't jet picked up in your iteration therefore anything inside won't either, Just a hunch, perhaps you could test this by assigning a `FrameWorkElement` to the `Tag` property and see if that gets picked up in your loop. But like I said its just a guess :) – sa_ddam213 May 03 '13 at 12:20
  • @sa_ddam213 I'll try, now using http://wpfinspector.codeplex.com/ I'm able to see the entire structure. – Francesco De Lisi May 03 '13 at 12:50

0 Answers0