Search code examples
c#searchtreeview

C# TreeView search function implementation


I'm currently trying to implement a search function in a little project i have going on.A little background about the project, i have an xml from where i import some data stored in a treeview.My goal is to be able to give a string and display in the treeview only the nodes that contain that particular string.

For the xml below my treeview looks like this

 Breakfast
     Belgian waffles
     Strawberry Belgian Waffles 

If i select a node, i have a groupbox with some textboxes that contains the properties of every item(price, calorie, etc.)

I want my function to be able to search for anything..i.e if i give a price, to display the item/items in the treeview with that price,if i search for waffles to display all the waffles.

<breakfast_menu>
  <food>
    <name>Belgian Waffles</name>
    <price>$5.95</price>
    <description>
      Two of our famous Belgian Waffles with plenty of real maple syrup
    </description>
    <calories>650</calories>
  </food>
  <food>
    <name>Strawberry Belgian Waffles</name>
    <price>$7.95</price>
    <description>
      Light Belgian waffles covered with strawberries and whipped cream
    </description>
    <calories>900</calories>
  </food>
</breakfast_menu>

I have a recursive function but at the 3rd(TreeNode t = treeNode.FirstNode) line it pops a null reference exception.My guess is that this exception pops when it hit's a node with no childs but i do not now how to handle it.

private void IterateRecursive(TreeNode treeNode)
        {
            TreeNode t = treeNode.FirstNode;
            if (t!=null)
            {
                foreach (TreeNode tn in treeNode.Nodes)
                {
                    IterateRecursive(tn);
                }
            }
            if (!treeNode.Text.Contains(textBox_search_string.ToString()))
            {
                treeView1.Nodes.Remove(treeNode);
            }
        }

Also, if there is a different way i can make this search function i am open to suggestions.


Solution

  •      public static void Search(string s)
            {
              bool node_add_decision = false;
              int i = 0;
              foreach (XmlNode p_node in xml_list)
              {
                    i++;
                    node_add_decision = false;
                    if (p_node.Attributes.Count > 0)
                    {
                        foreach (XmlAttribute attr in p_node.Attributes)
                        {
                            if (attr.Name.Contains(s) || attr.Value.Contains(s))
                            {
                                node_add_decision = true;
                            }
                        }                  
                        if (!node_add_decision)
                        {
                            node_add_decision=search_c(p_node, s);
                        }
                    }
                    if (node_add_decision)
                    {
                        Add_search_list(p_node,i);
                    }
                 }
             }
    
      private static bool search_c(XmlNode xn, string s)
        {
          if (xn.HasChildNodes)
                {
                    foreach (XmlNode chld in xn.ChildNodes)
                    {
                            for (int i = 0; i <= chld.ChildNodes.Count - 1; i++)
                            {
                                if(chld.ChildNodes[i].Value!=null)
                                {
                                    if (chld.ChildNodes[i].Value.Contains(s))
                                        return true;
                                }
                                if (chld.ChildNodes[i].Name.Contains(s))
                                {
                                    return true;
                                }
                                else {
                                    if (chld.ChildNodes[i].Attributes.Count > 0)
                                    {
                                        foreach (XmlAttribute attr in chld.ChildNodes[i].Attributes)
                                        {
                                            if (attr.Name.Contains(s) || attr.Value.Contains(s))
                                            {
                                                return true;
                                            }
                                        }
                                    }                            
                            }
                        }
                    }
                }
                return false;
            }
    

    So, i got the main function called Search, for every node that i have in the list it will search the desired string in all it;s attributes.If found, than node_add_decision will be set to true, meaning that the node contains the string and it is no longer needed to search it's childs.If in the current node there is no trace of the string, the node decision will be false meaning that we have to search it's childs.

    search_c is the function to search the string through the childs.For every child node we search for the string and if found return true, else false.

    For my case, i had to display event it doesn't contain the string, but a child of it does.If this is not ur case, u can ditch the search_c function and the node decision part of code.