动态递归怎么写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