当前位置:编程学习 > C#/ASP.NET >>

动态递归怎么写Treeview

       
手工添加这样可以实现
树结构:
        tv.BackColor = Color.Snow
        tv.Nodes.Add("北京市", "北京市")
        tv.Nodes("北京市").Nodes.Add("西城区", "西城区")
        tv.Nodes("北京市").Nodes.Add("海淀区", "海淀区")
        tv.Nodes("北京市").Nodes.Add("顺义县", "顺义县")

        tv.Nodes.Add("甘肃省", "甘肃省")
        tv.Nodes("甘肃省").Nodes.Add("兰州市", "兰州市")
        tv.Nodes("甘肃省").Nodes.Add("天水市", "天水市")
        tv.Nodes("甘肃省").Nodes.Add("白银市", "白银市")
        tv.Nodes("甘肃省").Nodes.Add("嘉峪关市", "嘉峪关市")

        tv.Nodes("甘肃省").Nodes("兰州市").Nodes.Add("城关区", "城关区")
        tv.Nodes("甘肃省").Nodes("兰州市").Nodes.Add("七里河区", "七里河区")

但是动态从数据库取,递归算法不会写,请人帮忙,谢谢 --------------------编程问答-------------------- 表有两个 

"学期 "表 
学期编号   学期名称 
    1               aaaa 
    2               bbbb 
    3               cccc 

"考试 "表 
考试编号   学期编号   考试名称   考试信息 
    1                 1                   ddd             eee 
    2                 1                   fff             ggg 
    3                 2                   hhh             iii 

Imports   System.Data 
Imports   System.Data.OleDb 
Public   Class   Form2 
        Inherits   System.Windows.Forms.Form 


'找出树中当前节点的级数 
Public   Function   NodeLevel(ByVal   n   As   TreeNode)   As   Byte     
                Dim   i   As   Byte   =   1 
                Do   Until   n.Parent   Is   Nothing 
                        n   =   n.Parent 
                        i   +=   1 
                Loop 
                Return   i 
End   Function 

Private   Sub   Form2_Load(ByVal   sender   As   System.Object,   ByVal   e   As   System.EventArgs)   Handles   MyBase.Load 
                Dim   strConn   As   String   =   "provider=Microsoft.jet.OLEDB.4.0;Data   Source=信息.mdb " 
                Dim   objConn   As   New   OleDbConnection(strConn) 
                Dim   objCmd   As   New   OleDbCommand 
                Dim   strCmd   As   String 

                Try 
                        objConn.Close() 
                        objConn.Open() 

                        strCmd   =   "select   *   from   学期 " 
                        objCmd.CommandText   =   strCmd 
                        objCmd.Connection   =   objConn 
                        Dim   mysqlreader   As   OleDbDataReader   =   objCmd.ExecuteReader 


                        TreeView1.Nodes.Clear() 

                        While   mysqlreader.Read() 

                                Dim   tree_root   As   New   TreeNode 

                                tree_root.Tag   =   mysqlreader.GetString(0)       

                                tree_root.Text   =   mysqlreader.GetString(1)   
                                
                                TreeView1.Nodes.Add(tree_root) 

                        End   While 

                Catch   ex   As   Exception 

                        MessageBox.Show(ex.ToString,   "数据表根节点载入错误 ") 

                Finally 

                        objConn.Close() 

                End   Try 

                TreeView1.ExpandAll() 

                TreeView1.Select() 

        End   Sub 

Private   Sub   TreeView1_AfterSelect(ByVal   sender   As   System.Object,   ByVal   e   As   System.Windows.Forms.TreeViewEventArgs)   Handles   TreeView1.AfterSelect 

                Dim   strConn   As   String   =   "provider=Microsoft.jet.OLEDB.4.0;Data   Source=信息.mdb " 
                Dim   objConn   As   New   OleDbConnection(strConn) 
                Dim   objCmd   As   New   OleDbCommand 
                Dim   strCmd   As   String 
                If   NodeLevel(e.Node).ToString   =   "1 "   Then 
                        If   e.Node.GetNodeCount(False)   =   0   Then 
                                strCmd   =   "select   *   from   考试   where   学期编号= ' "   &e.Node.Tag   &   " ' " 
                                    Try 

                                        objConn.Open() 
                                        objCmd.Connection   =   objConn 
                                        objCmd.CommandText   =   strCmd 
                                        Label1.Text   =   strCmd 
*********************************************************  
Dim   objReader   As   OleDbDataReader   =   objCmd.ExecuteReader 
*********************************************************

                                        While   objReader.Read() 

                                                Dim   leaf_node   As   new   TreeNode 
                                                leaf_node.Tag   =   objReader.GetString(0) 
                                                leaf_node.Text   =   objReader.GetString(2) 
                                                TreeView1.SelectedNode.Nodes.Add(leaf_node) 
                                        End   While 
                                Catch   ex   As   Exception 
                                        MessageBox.Show(ex.ToString,   "数据表子节点载入错误 ") 
                                Finally 
                                        objConn.Close() 
                                End   Try 

                        End   If 
                End   If 
        End   Sub 


End   Class --------------------编程问答-------------------- 递归的标志是直接或间接的调用函数本身,你好象没调
递归是一个函数,最好不要在事件里写吧??
另外,代码内部做的事情是不会触发事件的,所以你写的这个....好象实现不了

楼主说的这个递归应该实现不了,也没必要用递归(才两张表而已).
把TreeView1_AfterSelect改成一个sub
TreeView1.Select()   这句改成调那个sub --------------------编程问答-------------------- 没看出来1楼的表和上面有啥关联。。。。


说地区这回事

首先你的数据库中,肯定不能只有地区的名字,每个名字应该对应一个编号,这个编号记录了这个地区到底属于哪个市哪个省
所以可以根据这个编号来确定要添加到哪个NODE下面
其次一点,建议用循环遍历这个表,而不是用递归,
递归的话一个降低了程序的可读性,另一个递归对系统的开销可是很大的。。。尤其是你递归的次数非常多的时候

具体咱来想想怎么做这个循环
我的数据库里地区编号用的是国家行政区划最新版
这个编号是个6位数,XXYYZZ(省编号,市编号,区编号各两位)


用下面这一段前假设你已经把国家行政区划这张破表加载到ds.Tables(0)中了

        Dim currPid As Integer = -1 '当前一级Node的索引
        Dim currCid As Integer = -1 '当前二级Node的索引
        '之所以要用两个变量作为索引,是因为倒霉的国家行政区划的省ID和市ID并不连续
        '不能通过对地区ID的运算得到索引值

        Dim dr As DataRow
        For Each dr In ds.Tables(0).Rows

            '如果地区编号后4位为0,则表示这是一个省
            '把这个地区作为一级节点添加到tv
            'currPid自加1,currCid初始化
            If (dr.Item("areaID") Mod 10000) = 0 Then
                Me.tv.Nodes.Add(dr.Item("areaName"))
                currPid += 1
                currCid = -1
                GoTo continue
            End If

            '此时地区编号肯定已经不是省,因为如果是省则运行完上面的IF已经跳出
            '如果地区编号的后2两为0,则表示这是一个市
            '把这个地区作为二级Node添加到当前一级Node下
            'currCid自加1
            If (dr.Item("areaID") Mod 100) = 0 Then
                Me.tv.Nodes(currPid).Nodes.Add(dr.Item("areaName"))
                currCid += 1
                GoTo continue
            End If

            '此时地区编号已经不是省或市,所以是一个区
            '把这个地区作为易做图Node添加到当前二级Node下
            'currCid自加1,currAid初始化
            Me.tv.Nodes(currPid).Nodes(currCid).Nodes.Add(dr.Item("areaName"))

continue:
        Next

--------------------编程问答-------------------- 国家行政区划这表你要的话可以发你,MSN:maxzhk@163.com,加我跟我说一声就好了 --------------------编程问答-------------------- 10分感谢你的回答。我给你发了个Email,请给我发送一个吧。 --------------------编程问答-------------------- 发了 --------------------编程问答-------------------- 非常感谢好心人帮忙。研究中。。。 --------------------编程问答-------------------- 怎么给不了分呢??????????? --------------------编程问答-------------------- 老提示密码有误。 --------------------编程问答-------------------- don't care
分不分无所谓的,能帮到你就好 --------------------编程问答-------------------- 谢谢。
还要麻烦你啊。
呵呵

如:表结构为areaid       ;areaname   

难点在 
传递数据的时候,只能传递treeview1.selectednode.text(显示的是areaname),我想传递ID值,(如:每个areaid对应一个areaname)。请问如何将ID值跟Treeview节点值发生联系,我调用的时候直接调用areaid,而不是areaname。   

例如: 

---------------------------------------------- 
---山东省 
            ---济南市 
                  ----东城区 
                  ----西城区 
---------------------------------------------- 
  
然后点击   东城区   后,右边   DatagridView   显示   东城区   有多少个片区,以及详细信息。 


请问如何实现???   


急等===========等============================= --------------------编程问答-------------------- 递归方法不是很好,数据深度大且多的话,会慢得惊人 --------------------编程问答-------------------- Me.tv.Nodes(currPid).Nodes.Add(dr.Item("areaName")) 
Nodes(currPid)是什么意思?可以这样用么? --------------------编程问答-------------------- 最小版的 递归

/** SQLServer Sql Generate **/

create table  dept
(
       deptCode          VARCHAR(50) not null,
       deptName          VARCHAR(50),
       fartherCode       VARCHAR(50)
);
alter  table dept
       add constraint PK_deptCode primary key (deptCode);
EXEC sp_addextendedproperty 'MS_Description', '部门表', 'user', dbo, 'table', dept, NULL, NULL;
EXEC sp_addextendedproperty 'MS_Description', '部门代码', 'user', dbo, 'table', dept, 'column', deptCode;
EXEC sp_addextendedproperty 'MS_Description', '部门简称', 'user', dbo, 'table', dept, 'column', deptName;
EXEC sp_addextendedproperty 'MS_Description', '上级部门编码', 'user', dbo, 'table', dept, 'column', fartherCode;



 Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click

        TreeView1.Nodes.Clear()

        '创建一个节点对象,并初始化
        Dim tmp As TreeNode
        tmp = New TreeNode("所有部门")
        tmp.Text = "000"
        '在TreeView组件中加入兄弟节点
        TreeView1.Nodes.Add(tmp)
        TreeView1.ExpandAll()
        getitem(tmp)

    End Sub
    '加子节点
    Sub getitem(rootitem As TreeNode)

        Dim dt As DataTable = getChild(rootitem.Text)

        For Each dr As DataRow In dt.Rows
            Dim tmp As TreeNode
            tmp = New TreeNode(dr("deptcode"))
            tmp.Text = dr("deptcode")
            '在TreeView组件中加入子节点
            rootitem.Nodes.Add(tmp)
            'TreeView1.SelectedNode = tmp
            TreeView1.ExpandAll()
            getitem(tmp)
        Next


    End Sub


    Function getChild(root As String) As DataTable
        Dim strSQL As String = "select * from dept where farthercode='" & root & "'"
        Dim dt As New DataTable
        Dim sda As New SqlDataAdapter(strSQL, conn)
        sda.Fill(dt)
        Return dt

    End Function --------------------编程问答--------------------

'向下递归
    Private Sub foreward(ByVal parent As TreeNode)
        For Each child As TreeNode In parent.Nodes
            If child IsNot Nothing Then
                child.Checked = parent.Checked
                foreward(child)
            End If
        Next
    End Sub

    '向上递归
    Private Sub backward(ByVal child As TreeNode)
        Select Case child.Level
            Case Is > 0
                Dim b As Boolean = True
                For Each Node As TreeNode In child.Parent.Nodes
                    If Node IsNot Nothing Then b = b And Node.Checked
                Next
                child.Parent.Checked = b
                backward(child.Parent)
        End Select
    End Sub

    '点击后此过程只许运行一次!
    Private only As Boolean = True
    Private Sub TreeView_AfterCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterCheck
        If Not only Then Return
        only = False
        foreward(e.Node)
        backward(e.Node)
        only = True
    End Sub


补充:.NET技术 ,  VB.NET
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,