Getting Index of Selected TreeView Node in WPF

(The source code is attached.) 

Recently I received a request from one of my followers on how to get an index of a selected node in a WPF TreeView. Hence I am posting the same code here.

Let's create a basic TreeView with all the items added in XAML as: 

<Window x:Class="WPFSample.MainWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="MainWindow" Height="350" Width="525">

  <Grid>

    <TreeView x:Name="Tree">

      <TreeViewItem Header="One">

        <TreeViewItem Header="One-1">

          <TreeViewItem Header="One-1-1"/>

        </TreeViewItem>

        <TreeViewItem Header="One-2">

          <TreeViewItem Header="One-2-1"/>

        </TreeViewItem>

        <TreeViewItem Header="One-3">

          <TreeViewItem Header="One-3-1"/>

        </TreeViewItem>

        <TreeViewItem Header="One-4">

          <TreeViewItem Header="One-4-1"/>

        </TreeViewItem>

      </TreeViewItem>

      <TreeViewItem Header="Two">

        <TreeViewItem Header="Two-1">

          <TreeViewItem Header="Two-1-1"/>

        </TreeViewItem>

        <TreeViewItem Header="Two-2">

          <TreeViewItem Header="Two-2-1"/>

        </TreeViewItem>

      </TreeViewItem>

    </TreeView>

  </Grid>

</Window>

Once XAML is ready, the next step is to handle the event for a selected node that will show us the index of the selected node. The event provided by WPF for a selected item is 'SelectedItemChanged'. Let's add that event into XAML as:

<Grid>

  <TreeView x:Name="Tree" SelectedItemChanged="Tree_SelectedItemChanged">

    <TreeViewItem Header="One">

 

      <TreeViewItem Header="One-1">

        <TreeViewItem Header="One-1-1"/>

      </TreeViewItem>

      ....

      ....

    </TreeView> 

</Grid> 

Until here, we are done with our XAML part. Let's move on to code-behind, wherein we will handle the SelectedItemChanged event. Our code for the event handler will be as follows:

private void Tree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)

{

   int index = 0;

   if (Tree.Items.Count >= 0)

   {

      var tree = sender as TreeView;

      if (tree.SelectedValue != null)

      {

          index++;

          TreeViewItem item = tree.SelectedItem as TreeViewItem;

          ItemsControl parent = ItemsControl.ItemsControlFromItemContainer(item);

          while (parent != null && parent.GetType() == typeof(TreeViewItem))

         {

            index++;

            parent = ItemsControl.ItemsControlFromItemContainer(parent);

         }

         indexOfSelectedNode = index;

     }

  }

  MessageBox.Show(indexOfSelectedNode.ToString());

In the code above, ItemsControlFromItemContainer is the static method of ItemsControl. Uisng this method, one can retrieve the parent of the selected node. Once you have found the parent, the next step is just to create the loop required to find the index.

After doing all this, let's run the application and click on a node. You will land up to the corresponding index as shown below: