-4
\$\begingroup\$

How can I improve the tree searching algorithm, or can I?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        #region MyRegion
        private void button1_Click(object sender, EventArgs e)
        {
            TreeNode a = new TreeNode("A");
            TreeNode b = new TreeNode("B");
            TreeNode c = new TreeNode("C");
            TreeNode d = new TreeNode("D");
            TreeNode g = new TreeNode("G");
            TreeNode h = new TreeNode("H");
            TreeNode i = new TreeNode("I");
            TreeNode j = new TreeNode("J");
            TreeNode k = new TreeNode("K");
            TreeNode l = new TreeNode("L");
            TreeNode m = new TreeNode("M");
            TreeNode n = new TreeNode("N");
            TreeNode o = new TreeNode("O");
            TreeNode p = new TreeNode("P");
            TreeNode q = new TreeNode("Q");
            TreeNode r = new TreeNode("R");
            TreeNode s = new TreeNode("S");
            TreeNode t = new TreeNode("T");
            TreeNode u = new TreeNode("U");
            TreeNode v = new TreeNode("V");
            TreeNode w = new TreeNode("W");
            TreeNode x = new TreeNode("X");
            TreeNode y = new TreeNode("Y");
            TreeNode z = new TreeNode("Z");

            k.Nodes.Add(x);
            k.Nodes.Add(y);

            l.Nodes.Add(s);
            l.Nodes.Add(t);
            l.Nodes.Add(u);

            n.Nodes.Add(o);
            n.Nodes.Add(p);
            n.Nodes.Add(q);
            n.Nodes.Add(r);

            g.Nodes.Add(k);
            g.Nodes.Add(l);

            i.Nodes.Add(m);
            i.Nodes.Add(n);


            j.Nodes.Add(b);
            j.Nodes.Add(c);
            j.Nodes.Add(d);

            a.Nodes.Add(g);
            a.Nodes.Add(h);
            a.Nodes.Add(i);
            a.Nodes.Add(j);

            treeView1.Nodes.Add(a);
            treeView1.ExpandAll();

            button1.Enabled = false;
        } 
        #endregion

The tree-searching algorithm starts here:

        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            TreeNode selectedNode = e.Node;
            bool checkedStatus = e.Node.Checked;            

            //Children must be processes before parent
            if (HasChildrens(selectedNode))
            {
                CheckAllChildNodes(selectedNode, checkedStatus);
            }
            if (HasParent(selectedNode))
            {
                CheckAllParentNodes(selectedNode, checkedStatus);
            }
        }

        private bool HasParent(TreeNode node)
        {
            return node.Parent == null ? false : true;
        }

        public bool HasChildrens(TreeNode node)
        {
            if (node.Nodes == null) return false;
            else return true;
        }

        void CheckAllParentNodes(TreeNode node, bool check)
        {
            while(node!=null)
            {
                bool anyChildChecked = IsAnyChildChecked(node);

                if (anyChildChecked == true)
                {
                    node.Checked = true;
                }
                else
                {
                    node.Checked = check;
                }

                //Traversing
                node = node.Parent;
            }
        }

        void CheckAllChildNodes(TreeNode node, bool check)
        {
            foreach(TreeNode n in node.Nodes)
            {
                n.Checked = check;

                CheckAllChildNodes(n, check);
            }
        }

        bool IsAnyChildChecked(TreeNode node)
        {
            bool returns = false;

            foreach(TreeNode n in node.Nodes)
            {
                if (n.Checked == true) return true;

                returns = IsAnyChildChecked(n);
            }

            return returns;
        }
    }
}

enter image description here

enter image description here

\$\endgroup\$
  • 5
    \$\begingroup\$ How can I improve the following code? - start with an explanation what it's doing any why etc. \$\endgroup\$ – t3chb0t Mar 29 '17 at 4:15
1
\$\begingroup\$

The method IsAnyChildChecked would always return false if the last child and its subchilds is not checked. Therfore should return true on a positive substructure check too.

Like this:

bool IsAnyChildChecked(TreeNode node)
{
    foreach (TreeNode n in node.Nodes)
    {
        if (n.Checked || IsAnyChildChecked(n))
            return true;
    }

    return false;
}
\$\endgroup\$
  • \$\begingroup\$ I am not finding any difference during testing. \$\endgroup\$ – user3804 Mar 29 '17 at 8:37
  • \$\begingroup\$ If you call the original method for node G in the example and only node X is checked the result would be false. Because the positive check of node K would be overwriten with the negative result of node L. \$\endgroup\$ – Martin Mar 29 '17 at 9:02
  • \$\begingroup\$ How can I simulate this scenario? what should i click after what? \$\endgroup\$ – user3804 Mar 29 '17 at 9:17
  • \$\begingroup\$ Create the tree like in the excample you posted, set only node X checked and call the method IsAnyChildChecked for node G. \$\endgroup\$ – Martin Mar 29 '17 at 9:28
  • \$\begingroup\$ Why would I need to do that? The code I supplied is working perfectly. Its meant to be used to assign roles and privileges to system-users. \$\endgroup\$ – user3804 Mar 29 '17 at 9:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy