C#动态生成一个目录树

1.在生成一个目录树时,如果节点不多,我们可以采用硬编码的方式添加节点,比如这样:

 TreeNode tn1 = treeView1.Nodes.Add("一级部门1");
            TreeNode tn2 = treeView1.Nodes.Add("一级部门2");
            TreeNode tn3 = treeView1.Nodes.Add("一级部门3");

            TreeNode tn11 = new TreeNode("二级部门11");
            TreeNode tn21 = new TreeNode("二级部门21");
            TreeNode tn31 = new TreeNode("二级部门31");
            tn1.Nodes.Add(tn11);
            tn2.Nodes.Add(tn21);
            tn3.Nodes.Add(tn31);

            TreeNode tn111 = new TreeNode("三级部门111");
            TreeNode tn211 = new TreeNode("三级部门211");
            TreeNode tn311 = new TreeNode("三级部门311");
            tn11.Nodes.Add(tn111);
            tn21.Nodes.Add(tn211);
            tn31.Nodes.Add(tn311);

想要实现的效果:

C#动态生成一个目录树_第1张图片

2.但是如果节点增多的话,这样的方式就会显的累赘,而且相当冗长,那么我们可以采用递归的方式来遍历目录树:

首先,在数据库中的表的结构是这样子的:

C#动态生成一个目录树_第2张图片

表中的branch_path字段是目录树中节点值的路径字段,像这样:一级部门1/二级部门11/三级部门111,这在添加节点时非常有用;

branch_tree字段是为每一层节点设置的一个字段,比如说第一层的根节点为1,其余的依次递增;

以上两个字段其实完全没有必要!!这是我在探索动态添加目录树时经历的曲折艰辛道路而设置的字段,

请注意:从  3  到 4 这两步是我用循环遍历的方式添加目录树,但是是一个失败品,它只能添加一层,所以如果你想知道正确的方式,请参阅第5步,但是在3 到4 这两步中也有一些编程小知识点,也有可取之处

3.这样,在动态生成目录树时的代码就是:

         try
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.CommandType = CommandType.Text;
                cmd.Connection = conn;
                for (int i=1;i<4;i++)
                {
                    cmd.CommandText = "SELECT " +
                                "branch_code,branch_name,branch_hasSon,branch_parentCode,branch_path FROM tb_branch where branch_tree="+i;//i参数是数据库中部门表中为了界定树的层级而设置的
                    SqlDataAdapter sda = new SqlDataAdapter();
                    sda.SelectCommand = cmd;
                    DataTable dt = new DataTable();
                    sda.Fill(dt);//将查询的数据装如DataTable中
                    //遍历DataTable                   
                    if (i==1)
                    {
                        TreeNode tnRoot = null;
                        foreach (DataRow dr in dt.Rows)
                        {
                             tnRoot = treeView1.Nodes.Add(dr[1].ToString().Trim());
                        }
                    }
                    else
                    {
                        foreach (DataRow dr in dt.Rows)//遍历非根节点
                        {                          
                            string branchPath = dr[4].ToString().Trim();
                            string[] arr = branchPath.Split(new char[] { '/' });
                            if (arr.Length == 3)
                            //遍历非根节点的最后一层节点,因为遍历中间的节点没有意义,而且我至今未找到知道一个节点Text的值,如何
                            //得到该节点,所以我在数据库中设立了branch_path字段,通过截取字符串,在最后一层添加整个目录树的非根节点
                            {
                                foreach (TreeNode tnRoot in treeView1.Nodes)
                                {
                                    TreeNode tn1 = new TreeNode(arr[1]);
                                    if(tnRoot.Text==arr[0])
                                    {
                                        tnRoot.Nodes.Add(tn1);
                                        TreeNode tn2 = new TreeNode(arr[2]);
                                        tn1.Nodes.Add(arr[2]);
                                    }
                                }
                            }
                        }
                    }
                   
                }
                             
            }
            catch(Exception ex)
            {


            }
            finally
            {
                conn.Close();
            }

4.至此,我们就动态生成了一个目录树,效果如下:

这样的目录树并不是通过treeView的事件生成的,而是在加载窗体时就形成了。

C#动态生成一个目录树_第3张图片

5.递归生成目录树!!(这才是正确的方法)

    首先,数据库中的表的和上面的相同;可以去掉branch_path,branch_tree,branch_hasSon

    必须要有的字段:branch_id,branch_code,branch_name,branch_parentCode.

    其次,在代码中这样写(我将这部分代码写道了一个初始化方法中):

    OtherInit3是添加目录树的方法

        public Form1()
        {
            LinkToDB();
            InitializeComponent();
            //OtherInit();//其他初始化事件
            //OtherInit2();
            OtherInit3();
        }
        DataTable dt0;//声明一个全局的DataTable
        private void OtherInit3()
        {
            try
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = "select * from tb_branch";
                cmd.Connection = conn;
                SqlDataAdapter sda = new SqlDataAdapter();
                sda.SelectCommand = cmd;
                dt0= new DataTable();
                sda.Fill(dt0);
                conn.Close();
                //TreeView tv;//树控件
                //获得第一级数据,即根目录
                DataRow[] drRoot = dt0.Select("len(branch_code)=1");
                foreach (DataRow dr in drRoot)
                {
                    TreeNode tn = new TreeNode();
                    tn.Text = dr["branch_name"].ToString();
                    treeView1.Nodes.Add(tn);
                    AppendChild(tn, dr["branch_code"].ToString());
                    
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            finally
            {
                conn.Close();
            }
        }
        private void AppendChild(TreeNode tnParent, string branch_code)   //递归添加节点
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "select branch_code from tb_branch where branch_name='"+tnParent.Text+"'";
            cmd.Connection = conn;
            string branchCode=(string)cmd.ExecuteScalar();//branchCode是父节点的code
            conn.Close(); 
            DataRow[] drs = dt0.Select("(branch_parentCode)="+branchCode+" and len(branch_code)= "+(branch_code.Length+1));//DataTable有Select方法来筛选DataRow,你可以在网上查到这些方法进行了解,此处不再赘述
            //int a = drs[0]["branch_code"].ToString().Length;
            if(drs!=null)
            {
                foreach (DataRow dr in drs)
                {
                    TreeNode tn = new TreeNode();

                    tn.Text = dr["branch_name"].ToString();                  
                    tnParent.Nodes.Add(tn);
                    AppendChild(tn, dr["branch_code"].ToString());
                }
            }
            
        }

至此,就可以在数据库中添加任意多条数据,前台动态生成这些节点。

注意:branch_code.Length的长度递增取决于你的部门的编号,我的是1,2,3,11,21,31,像这样

C#动态生成一个目录树_第4张图片

如果你是001,001001001,002,002001,那么你的递增书就不是1了,而是按照你的递增规律来写。


你可能感兴趣的:(C#)