How to Retrieve WPF Visual Tree Programmatically ?

By | August 4, 2011

In previous tip, Abhishek discussed about basic of Logical and Visual Tree in WPF.  In this tip I am going to explain how you can retrieve and examine the Visual Tree programmatically in WPF. The VisualTreeHelper provides few API Methods GetChildrenCount(), GetChild() and GetParent() using which you can get details of the Visual Tree structure.

VisualTreeHelper.GetChildrenCount() method returns the number of child visuals, that the parent visual contains and VisualTreeHelper.GetChild() method helps to get the index value of the child visual object. Using the VisualTreeHelper.GetChild()  you can traverse through the visual tree of any window or child control.

To implement the same, below is the snippet for XAML where I have one Button and TreeView inside a Stack Panel and Grid is to top parent container.

image

On the Click of the Button we will be generating the Visual Tree. image

You must have noticed I have provided “this” as argument to the  method, which means, I want to generate the Visual Tree by considering “Main Window” as parent.

Below is the implementation for the ShowWPFVisualTree()  and AddElementsAtVisualTree() method.

image

You are done,  Click on “Show Visual Tree” button and you will get the complement visual Tree as show in below image.

image

If you want to make this bit simple, while calling ShowWPFVisualTree(), instead of passing “this” as argument, pass “grid1” as argument and run the application. You will find tree is starting from a Grid Control which contains a “Stack Panel” and Button and TreeView are the child controls.

image

You can Expand Button and TreeView ( Collapsed in the above image ) to get the inner tree structure.

Below is the complete Code Snippet

XAML :

<Window x:Class="WPFVisualTree.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Show Visual Tree" Height="450" Width="536">
    <Grid x:Name="grid1">
        <StackPanel>
            <Button Content="Show Visual Tree"
                    Name="btnShowVisualTree"
                    Margin="40,10,0,0"
                    Click="btnShowVisualTree_Click" 
                    Width="150"/>
            <TreeView Margin="0,10,0,0" 
                      Name="treeVisual" />
        </StackPanel>
    </Grid>
</Window>

Class :

  public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Handles the Click event of the btnShowVisualTree control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void btnShowVisualTree_Click(object sender, RoutedEventArgs e)
        {
            this.ShowWPFVisualTree(this.grid1);
        }

        /// <summary>
        /// Shows the WPF visual tree.
        /// </summary>
        /// <param name="element">The element.</param>
        public void ShowWPFVisualTree(DependencyObject element)
        {
            treeVisual.Items.Clear();
            AddElementsAtVisualTree(element, null);
        }
        /// <summary>
        /// Adds the elements at visual tree.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="previtem">The previtem.</param>
        private void AddElementsAtVisualTree(DependencyObject element, TreeViewItem previtem)
        {
            TreeViewItem item = new TreeViewItem();
            item.Header = element.GetType().Name;
            item.IsExpanded = true;

            if (previtem == null)
            {
                treeVisual.Items.Add(item);
            }
            else
            {
                previtem.Items.Add(item);
            }

            int totalElementcount = VisualTreeHelper.GetChildrenCount(element);

            for (int counter = 0; counter < totalElementcount; counter++)
            {
                AddElementsAtVisualTree(VisualTreeHelper.GetChild(element, counter), item);
            }
        }
    }

Hope this will helps !
Cheers !
Aj