Posted by: Zeeshan Amjad | January 15, 2011

Traversing Logical Tree


Traversing logical tree is very much similar to traversing the visual tree. There is one class to traverse logical tree which is very similar to the class that traverse the visual tree. Although the basic purpose of both classes are very similar, but there have slightly different interface. Here is a class diagram of LogicalTreeHelper.

LogicalTreeHelper

The first obvious difference is the number of methods in both classes. The other important difference is the signature of GetChildern method. In VisualTreeHelper class this method returns the int, but there it returns IEnumerable. It means when we are using this method, we can call the foreach loop with the return type. Here is recursive function to traverse all the logical elements in the logical tree.

Code Snippet
  1.     public void TraverseLogicalTree(Object obj, TreeViewItem tvi)
  2.     {
  3.         if (obj is DependencyObject)
  4.         {
  5.             var childern = LogicalTreeHelper.GetChildren(obj as DependencyObject);
  6.  
  7.             foreach (var child in childern)
  8.             {
  9.                 TreeViewItem tviChild = new TreeViewItem();
  10.                 tviChild.Header = child.GetType().ToString();
  11.  
  12.                 if (tree.Items.Count == 0)
  13.                 {
  14.                     tree.Items.Add(tviChild);
  15.                 }
  16.                 else
  17.                 {
  18.                     tvi.Items.Add(tviChild);
  19.                 }
  20.  
  21.                 TraverseLogicalTree(child, tviChild);
  22.             }
  23.         }
  24.     }
  25. }

 

Rest of the code is very much similar. Let’s make one simple program with some nested elements in XAML first. Here is XAML of our program.

Code Snippet
  1. <Window x:Class="WpfLogicalTree.MainWindow"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
  4.         Title="Logical Tree" Height="600" Width="800">
  5.     <Window.Resources>
  6.         <Style TargetType="TreeViewItem">
  7.             <Setter Property="IsExpanded" Value="True" />
  8.         </Style>
  9.     </Window.Resources>
  10.     <Grid>
  11.         <Grid.ColumnDefinitions>
  12.             <ColumnDefinition/>
  13.             <ColumnDefinition/>
  14.         </Grid.ColumnDefinitions>
  15.         <Grid.RowDefinitions>
  16.             <RowDefinition Height="7*"/>
  17.             <RowDefinition/>
  18.         </Grid.RowDefinitions>
  19.         
  20.         <TreeView Margin="5" Grid.Column="0" Grid.Row="0" Name="tree"/>
  21.         <Border Margin="5" Grid.Column="1" Grid.Row="0" Name="border">
  22.             <Grid>
  23.                 <Grid.ColumnDefinitions>
  24.                     <ColumnDefinition/>
  25.                     <ColumnDefinition/>
  26.                     <ColumnDefinition/>
  27.                 </Grid.ColumnDefinitions>
  28.                 <Grid.RowDefinitions>
  29.                     <RowDefinition/>
  30.                     <RowDefinition/>
  31.                 </Grid.RowDefinitions>
  32.                 <Rectangle Grid.Row="0" Grid.Column="0" Margin="3">
  33.                     <Rectangle.Fill>
  34.                         <LinearGradientBrush>
  35.                             <GradientStop Offset="0" Color="White"/>
  36.                             <GradientStop Offset="1" Color="Red"/>
  37.                         </LinearGradientBrush>
  38.                     </Rectangle.Fill>
  39.                 </Rectangle>
  40.                 <Rectangle Grid.Row="0" Grid.Column="1" Margin="3">
  41.                     <Rectangle.Fill>
  42.                         <LinearGradientBrush>
  43.                             <GradientStop Offset="0" Color="White"/>
  44.                             <GradientStop Offset="1" Color="Green"/>
  45.                         </LinearGradientBrush>
  46.                     </Rectangle.Fill>
  47.                 </Rectangle>
  48.                 <Rectangle Grid.Row="0" Grid.Column="2" Margin="3">
  49.                     <Rectangle.Fill>
  50.                         <LinearGradientBrush>
  51.                             <GradientStop Offset="0" Color="White"/>
  52.                             <GradientStop Offset="1" Color="Blue"/>
  53.                         </LinearGradientBrush>
  54.                     </Rectangle.Fill>
  55.                 </Rectangle>
  56.                 <Grid Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="3" Margin="3">
  57.                     <Grid.RowDefinitions>
  58.                         <RowDefinition/>
  59.                         <RowDefinition/>
  60.                     </Grid.RowDefinitions>
  61.                     <Border Grid.Row="0" Margin="2" BorderBrush="Brown" BorderThickness="2" CornerRadius="5">
  62.                         <TextBlock Margin="3"/>
  63.                     </Border>
  64.                     <Border Grid.Row="1" Margin="2" BorderBrush="Navy" BorderThickness="2" CornerRadius="5">
  65.                         <TextBox Margin="3"/>
  66.                     </Border>
  67.                 </Grid>
  68.                         </Grid>
  69.         </Border>
  70.         <Button Margin="5" Grid.Column="0" Grid.Row="1" Name="btnLogicalView" Click="btnLogicalView_Click">
  71.             Display Logical View
  72.         </Button>
  73.         <Button Margin="5" Grid.Column="1" Grid.Row="1" Name="btnExit" Click="btnExit_Click">
  74.             Exit
  75.         </Button>
  76.     </Grid>
  77. </Window>

 

And here is simple program to traverse all the element inside the border defined inside the first columns and 0th row of the grid. Here is complete coding of our program.

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. using System.Windows.Navigation;
  13. using System.Windows.Shapes;
  14.  
  15. namespace WpfLogicalTree
  16. {
  17.     /// <summary>
  18.     /// Interaction logic for MainWindow.xaml
  19.     /// </summary>
  20.     public partial class MainWindow : Window
  21.     {
  22.         public MainWindow()
  23.         {
  24.             InitializeComponent();
  25.         }
  26.  
  27.         private void btnLogicalView_Click(object sender, RoutedEventArgs e)
  28.         {
  29.             TreeViewItem tvi = new TreeViewItem();
  30.             TraverseLogicalTree(border, tvi);
  31.         }
  32.  
  33.         private void btnExit_Click(object sender, RoutedEventArgs e)
  34.         {
  35.             Close();
  36.         }
  37.  
  38.         public void TraverseLogicalTree(Object obj, TreeViewItem tvi)
  39.         {
  40.             if (obj is DependencyObject)
  41.             {
  42.                 var childern = LogicalTreeHelper.GetChildren(obj as DependencyObject);
  43.  
  44.                 foreach (var child in childern)
  45.                 {
  46.                     TreeViewItem tviChild = new TreeViewItem();
  47.                     tviChild.Header = child.GetType().ToString();
  48.  
  49.                     if (tree.Items.Count == 0)
  50.                     {
  51.                         tree.Items.Add(tviChild);
  52.                     }
  53.                     else
  54.                     {
  55.                         tvi.Items.Add(tviChild);
  56.                     }
  57.  
  58.                     TraverseLogicalTree(child, tviChild);
  59.                 }
  60.             }
  61.         }
  62.     }
  63. }

 

Here is the output of the program.

LogicalTreeOutput

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: