--------专业
CREATE TABLE [dbo].[series] (
[SID] [int] IDENTITY (100, 1) NOT NULL PRIMARY KEY,
[SNumber] [varchar] (100) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[SName] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[SDisable] [bit] NOT NULL 
)
---------项目CREATE TABLE [dbo].[groups] (
[GID] [int] IDENTITY (100, 1) NOT NULL PRIMARY KEY ,
[GNumber] [varchar] (100) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[GName] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[GDisable] [bit] NOT NULL ,
[SID] [int] NOT NULL REFERENCES  [dbo].[series] ON DELETE CASCADE
) ON [PRIMARY]
GO------科目CREATE TABLE [dbo].[subject] (
[SID] [int] IDENTITY (100, 1) NOT NULL PRIMARY KEY ,
[SNumber] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[SName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[SPassLine] [float] NOT NULL ,
[SSumMarks] [float] NOT NULL,
[SDisable] [bit] NOT NULL ,
[GID] [int] NOT NULL REFERENCES [dbo].[groups] ON DELETE CASCADE
) ON [PRIMARY]
GO-------章,节CREATE TABLE [dbo].[chapter] (
[CID] [int] IDENTITY (100, 1) NOT NULL PRIMARY KEY,
[CNumber] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL ,
[CName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[CInterID] [int] NULL ,
[FDisable] [bit] NOT NULL ,
[SID] [int] NOT NULL REFERENCES [dbo].[subject] ON DELETE CASCADE
) ON [PRIMARY]
GO
共有 4个表 下面一个表都是 应用上面一个表的主键..
最后一个表 比较特殊 除了引用上面表的主键外..还引用自己的主键,,其实是 2个表合成的..要求: 窗体显示的时候 只能 看到专业 
点击专业 + 号 显示项目 ,,一次类推 以上解决 有分 :
另外:; 点击子节点 有事件 ...
    右键点击 出现菜单 (添加 修改 删除...)仍然有分 :

解决方案 »

  1.   

    参考:http://www.mltang.com/article/35d57dc0-70cd-4286-8a02-8a7806267579.html
      

  2.   

    楼主你这样的表结构,好像不需要用到递归吧?!
    楼主你这样的表结构,不适合用递归.用嵌套循环应该就能搞定://循环1,读专业
    for(......)
    {
    //循环2,读某一专业下的所有科目
        for(......)
        {
            .....
         }}
      

  3.   

    很簡單的問題,當前顯示的下一層加個臨時節點,隻有在Tv_BeforeExpand事件時才讀取下一層數據
      

  4.   

    两种递归,一种是从父结点加字节点,注释的是把字节点向父结点上加
            
        //将数据填充到dataTable
                DataTable mytable = new DataTable();
                //构建表结构
                DataRow myRow;
                DataColumn Id = new DataColumn("Id", typeof(System.Int32));
                mytable.Columns.Add(Id);
                DataColumn Name = new DataColumn("Name", typeof(System.String));
                mytable.Columns.Add(Name);
                DataColumn ParentId = new DataColumn("ParentId", typeof(System.Int32));
                mytable.Columns.Add(ParentId);
                DataColumn SiteInfo = new DataColumn("SiteInfo", typeof(SiteInfo));
                mytable.Columns.Add(SiteInfo);
                //填充数据
                //注意i是从1开始的,因为数据库收条没有意义,数据库首条记录id为0,会引起死循环
                for (int i = 1; i <= cata.Length - 1; i++)
                {
                    myRow = mytable.NewRow();
                    myRow["Id"] = cata[i].Id;
                    myRow["Name"] = cata[i].Name;
                    myRow["ParentId"] = cata[i].ParentId;
                    myRow["SiteInfo"] = cata[i].SiteInfo;                mytable.Rows.Add(myRow);
                }
                this.InitTree(newNode.ChildNodes, 0, mytable);
                  //Hashtable ht = new Hashtable();            //for (int i = 1; i < cata.Length; i++)
                //{
                //    ht.Add(cata[i].Id, cata[i]);
                //}
                //Hashtable allTreeNodes = new Hashtable();
                //Hashtable parentNodes = new Hashtable();
                ////遍历树节点描述并拟向生成树结构
                //foreach (DictionaryEntry dict in ht)
                //{
                //    CatalogInfo treeobj = (CatalogInfo)dict.Value;
                //    if (allTreeNodes.Contains(treeobj.Id))
                //        continue;
                //    TreeNode tn = new TreeNode();
                //    tn.Text = treeobj.Name;
                //    tn.Value = treeobj.Id.ToString();
                //    tn.NavigateUrl = "main_right.aspx?catalogid=" + tn.Value;
                //    tn.Target = "WorkArea";
                //    generateParentTreeFromNode(tn, (CatalogInfo)treeobj, ht, parentNodes, allTreeNodes);
                //}            ////将所有根节点放到treeview上
                //foreach (DictionaryEntry dict in parentNodes)
                //{
                //    newNode.ChildNodes.Add((TreeNode)dict.Value);
                //}
            }
       }
        private void InitTree(TreeNodeCollection Nds, int parentID, DataTable dt)//递归初始化树
        {
            TreeNode tmpNd;
            //递归寻找子节点
            DataRow[] rows = dt.Select("ParentID=" + parentID);
            foreach (DataRow row in rows)
            {
                tmpNd = new TreeNode();
                tmpNd.Value = row["Id"].ToString();
                tmpNd.Text = row["Name"].ToString();
                tmpNd.NavigateUrl = "main_right.aspx?catalogid=" + row["Id"].ToString() + "&catalogName=" +Server.UrlEncode(row["Name"].ToString());
                tmpNd.Target = "WorkArea";
                Nds.Add(tmpNd);            InitTree(tmpNd.ChildNodes, Convert.ToInt32(tmpNd.Value), dt);
            }
        }
       /// <summary>
       /// 反向树生成算法
       /// </summary>
       /// <param name="subtr">子节点</param>
       /// <param name="subto">子节点描述对象</param>
       /// <param name="hashedTreeObject">被保存到哈希表中的子节点描述</param>
       /// <param name="hashedParents">被保存到哈希表中的父节点描述</param>
       /// <param name="allTreeNodes">被保存到哈希表中的所有节点描述</param>
       private void generateParentTreeFromNode(TreeNode subtr, CatalogInfo subto, Hashtable hashedTreeObject, Hashtable hashedParents, Hashtable allTreeNodes)
       {       TreeNode trParent;
           if (null == hashedTreeObject)
               return;
           //确定父结点是否存在
           if (!hashedTreeObject.Contains(subto.ParentId) || subto.ParentId == subto.Id )
           {
               //不存在则将当前节点作为根
               if (hashedParents == null)
                   hashedParents = new Hashtable();
               if (!hashedParents.Contains(subto.ParentId))
               {
                   hashedParents.Add(subto.Id, subtr);
                   if (!allTreeNodes.Contains(subto.Id))
                       allTreeNodes.Add(subto.Id, subtr);
                   trParent = subtr;
               }
           }
           else
           {
               //若存在,则获取父结点
               CatalogInfo to = (CatalogInfo)hashedTreeObject[subto.ParentId];
               //判断父结点是否已经被保存到树节点的哈希表中
               if (allTreeNodes.Contains(subto.ParentId))
               {
                   //if (allTreeNodes.Contains(subto.Id))
                   //    return;
                   trParent = (TreeNode)allTreeNodes[subto.ParentId];
                   trParent.ChildNodes.Add(subtr);
               }
               else
               {
                   //父结点不存在于哈希表中,创建父结点并存放到叶子哈希表中
                   trParent = new TreeNode();
                   trParent.Text = to.Name;
                   trParent.Value = to.Id.ToString();
                   allTreeNodes.Add(subto.ParentId, trParent);
                   trParent.ChildNodes.Add(subtr);
                   //递归向上查找
                   generateParentTreeFromNode(trParent, to, hashedTreeObject, hashedParents, allTreeNodes);
                   if (!allTreeNodes.Contains(subto.Id))
                       allTreeNodes.Add(subto.Id, subtr);
               }       }
       }
      

  5.   

    楼上的果然厉害,,,这么繁琐的问题,都写哈.支持:(用不到递归,用for就够用了.这个还考虑到性能)
    很簡單的問題,當前顯示的下一層加個臨時節點,隻有在Tv_BeforeExpand事件時才讀取下一層數據这是大致思路...,还有右键菜单的问题,当点击到treeview控件时判断是左键还是右键,如果是右键的话.弹出菜单,事先准备好的,单击事件 用选定的节点的某些参数修改数据库.
      

  6.   

    // 鼠标 右键
            private void tvShow_MouseDown(object sender, MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Right)
                {
                    TreeNode tn = tvShow.GetNodeAt(e.X, e.Y);
                    if (tn != null)
                    {
                        tvShow.SelectedNode = tn;
                    }
                }
            }
      

  7.   

    protected  void inittree()
            {
                tvShow.Nodes.Clear();
                DataView dv = Bind("select *from series").Tables[0].DefaultView;
                
                ds1 = Bind("select * from groups");
                ds2 = Bind("select *from subject");
                 if (dv.Table.Rows.Count > 0)
                {
                    foreach (DataRowView dr in dv)
                    {
                        TreeNode tn = new TreeNode();
                        tn.Text = dr[2].ToString();
                        tn.Tag = dr[0].ToString();
                      
                        tvShow.Nodes.Add(tn);
                        childnode_1(tn);
                       
                    }
                }
               }        protected void childnode_1(TreeNode tn)
            {
                int second =Int32.Parse( tn.Tag.ToString());
                DataView dv = ds1.Tables[0].DefaultView;
                if (dv.Table.Rows.Count > 0)
                {
                    dv.RowFilter = "SID=" + second;
                    if (dv.Count > 0)
                    {
                        foreach (DataRowView dr in dv)
                        {
                            TreeNode tn_2 = new TreeNode();
                            tn_2.Text = dr[2].ToString();
                            tn_2.Tag = dr[0].ToString();
                          
                            tn.Nodes.Add(tn_2);
                            childnode_2(tn_2);
                        }
                    }
                }
            }
    // 依次 类推...............
      

  8.   

    递归方法如:
     private   void   InitTree(DataTable   dt,Nodes Nds,string   parentId)   
            {   
                DataView   dv=new   DataView(dt);   
                Node   tmpNd;   
                dv.RowFilter = "parent_id=" + "'" + parentId + "'";  
                foreach(DataRowView   drv   in   dv)   
                {   
                    tmpNd=new   Node();   
                    tmpNd.DataKey=drv["id"].ToString();   
                    tmpNd.Text=drv["menu_name"].ToString(); 
                    if (parentId != "-1")
                    {
                        tmpNd.TargetUrl = drv["URL"].ToString();
                        tmpNd.TargetFrame="main";
                        tmpNd.ImageUrl = "pic/small0.gif";
                    }
                   else
                    {
                        tmpNd.ImageUrl = "pic/shequ_man.gif";
                    }
                    Nds.Add(tmpNd);   
                    InitTree(dt,tmpNd.Nodes,drv["id"].ToString());   
                }   
            } 
    调用如:
    ds = fac.GetMenuListDetail(Request.Cookies["uname"].Value.ToString());
                InitTree(ds.Tables[0],trees.Nodes,"-1");