Skip to main content Skip to footer

Searching Nodes in C1Treeview

C1TreeView is basically used to display Hierarchical data and can used in both bound and unbound mode. We can even show nested parent-child relationship by implementing C1HierarchicalDataTemplate and this has already been explained in this blog. This blog is an extended version which uses C1HierarchicalDataTemplate and allows end user to search the corresponding TreeView item. To begin with, bind the Treeview control with a DataTable and for that you may again refer to the previous blog mentioned above. After doing so, you have a C1Treeview bound to a self-referential data source. Actual implementation starts now. Objective of the blog is to provide a TextBox to the end user for input and corresponding Node with the input text will be searched in the C1TreeView. The basic concept is to traverse all the nodes of C1TreeView recursively till the search item is found and then, set it as expanded and selected. The searching is done on the basis of the DataRow object associated with the entered text in the DataTable. To do so, you need to handle the TextChanged event of the Textbox and find the associated DataRow in the DataTable . Then, use the ContainerFromIndex method of ItemContainerGenerator Class to get the parent item and check if it matches with the end user input. If it does, then set it selected else call custom SearchItem method in order to traverse its child items.


private void searchtb_TextChanged(object sender, TextChangedEventArgs e)  
 {  
   isfound = false;  
   var val = searchtb.Text;  
   if (!String.IsNullOrEmpty(val))  
    {  
     DataView dv = ds.Tables["data"].DefaultView;  
     var row = dv.Table.Rows.FirstOrDefault(r => r.ItemArray[2].ToString().StartsWith(val, StringComparison.OrdinalIgnoreCase));  

     for (int i = 0; i < searchTreeView.Items.Count; i++)  
      {  
        //get the parent node  
        var parentItem = searchTreeView.ItemContainerGenerator.ContainerFromIndex(i) as C1TreeViewItem;  
        var nodeText = ((C1.Silverlight.Data.DataRowView)(parentItem.Header)).GetData("NodeDescription").ToString();  
        //check if the search item is the parent node  
        if (nodeText.StartsWith(val, StringComparison.OrdinalIgnoreCase))  
           {  
             if (_last != null)  
             _last.IsExpanded = false;  

             parentItem.IsSelected = true;  
             _last = parentItem;  
             //set the textbox in focus  
              searchtb.Focus();  
              break;  
            }  
         else  
           {  
              if (isfound == false)  
                {  
                 //set the previous node to collapse  
                  if (_last != null)  
                    _last.IsExpanded = false;  

                 _last = parentItem;  
                 //expand this node  
                 parentItem.IsExpanded = true;  
                 parentItem.UpdateLayout();  
                 if ((parentItem != null) && (row != null))  
                   //call the custom expand to traverse the child nodes  
                    SearchItem(parentItem, row);  
                else  
                    parentItem.IsExpanded = false;  
               }  
            }  
       }  
   }  
 }  

The custom SearchItem method takes C1TreeViewItem and a DataRow object as parameters and runs recursively till the item is found. Here is the code for same:


//custom method for searching the nodes recursively  
public void SearchItem(C1TreeViewItem item, DataRow row)  
 {  
   if (item != null)  
   {  
    //check if it contains the searched item  
    var childItem = item.ItemContainerGenerator.ContainerFromItem(row.GetRowView() as DataRowView) as C1TreeViewItem;  
    //if child node is the required node  
    if (childItem != null)  
     {  
      childItem.IsExpanded = true;  
      childItem.IsSelected = true;  
      //set the flag to true  
      isfound = true;  
      searchtb.Focus();  

      return;  
     }  
   //else expand to next level  
    else  
     {  
       for (int i = 0; i < item.Items.Count; i++)  
        {  
          var parentItem = item.ItemContainerGenerator.ContainerFromIndex(i) as C1TreeViewItem;  
          parentItem.IsExpanded = true;  
          parentItem.UpdateLayout();  

          //call this method recursively  
          SearchItem(parentItem, row);  
        }  
     }  
   }  
 }  

Download the attached samples for complete implementation.

MESCIUS inc.

comments powered by Disqus