VB.NET中动态加载Treeview节点

最近写项目需要用到TREEVIEW树控件承载后台数据源.其中碰到一些难题,特别是在树控件对大量数据读取速度的算法编写上碰到很多问题....在网上找了一些关于这方面的资料,跟大家一起分享一下.

    Treeview是一个重要的控件,无论是在VB.NET,C#还是Delphi、VC++等各种语言中,都充当了导航器的作用。在实际工作中,很多情况下需要将Treeview与数据库进行连接,以填充其节点。然而,往往由于数据库数据众多,一次性灌入所有的根节点与子节点,会耗用大量的起始等待时间。解决的方案,应该是动态加载节点,起始的时候,只加载根节点,在点击某个根节点时,才加载其子节点,再点击某个子节点时,才加载子节点的子节点,以此类推,这样的处理方法可以达到提高工作效率,节省访问时间的妙用。

    本文仅以VB.NET为例,说明此方法的使用。其它的编程语言,可以进行仿效.

    首先应该有个数据库,用以保存数据结构与数据。本文需要的数据库为一个Project.mdb。其结构为(为清楚起见,以汉字字段为例,实际应用时,请自行更改):

表名:根节点

字段 类型 大小 主键
 
根节点编号 文本 10 Y
 
根节点名称 文本 10
 

表名:第一级子节点

字段 类型 大小 主键
 
根节点编号 文本 10 Y
 
第一级子节点编号 文本 10 Y联合主键
 
第一级子节点名称 文本 10 
 

表名:第二级子节点

字段 类型 大小 主键
 
第一级子节点编号 文本 10 Y
 
第二级子节点编号 文本 10 Y联合主键
 
第二级子节点名称 文本 10
 

    三个表的关系已经很清楚了,在此不再罗列。表内填充的数据为:

    根节点编号为1、2、3这样类推,其名称也就为根节点1、根节点2、根节点3

    第一级子节点编号规则为:根节点1之下的子节点编号为11、12、13等以此类推,根节点2之下的子节点编号为21、22……子节点名称为:子节点1、子节点2……

    第二级子节点编号规则为:第一级子节点ij之下的第二级子节点的编号为ij1、ij2……,其名称为统一的:孙节点1、孙节点2……

    现在让我们简单分析一下treeview的结构(笔者准备在另文专门剖析一下Treeview的结构,以方便有兴趣的网友进行高级应用)

    Treeview是由节点TreeNode组成的,第一级的称之为根节点TreeRoot,在根节点之下一级的称之为某个根节点的子节点TreeLeaf,某个子节点之下一级的子节点就称为该子节点的子节点。第个节点有两个标识方式,一个是它的Text,即显示出来的内容;另一个是它的Tag属性,一般用唯一标识码对其进行标识,以用于在使用时对节点的识别。在本文中,也主要用Text属性来显示节点的名称字段,用Tag属性来显示节点的编号属性。(节点编号被设为主键,也就是唯一的标识了)


    1.加载根节点

    好了,我们该开始在VB.NET中进行演练了!第一步,当然是看看怎么在窗体起始的时候加载根节点:

   '定义公用变量

    Dim myconnection As New OleDb.OleDbConnection()

    Dim MyAdapater As New OleDb.OleDbDataAdapter()

    Dim mycommand As New OleDb.OleDbCommand()

    Dim ds As New DataSet()

 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
     Handles MyBase.Load

        '载入根节点表至treeview中,作为第一级

        myconnection.ConnectionString = 
        "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=
        " & Application.StartupPath & "/project.mdb"  
        '数据库连接请自行更换

        mycommand.CommandText = "SELECT 根节点编号,根节点名称 FROM 根节点"

        mycommand.Connection = myconnection

        Try

            myconnection.Close()

            myconnection.Open()

            Dim mysqlreader As OleDb.OleDbDataReader = mycommand.ExecuteReader

            TreeView1.Nodes.Clear()

            While mysqlreader.Read()

                Dim tree_root As New TreeNode()

                tree_root.Tag = mysqlreader.GetString(0) '把编号放入tag中

                tree_root.Text = mysqlreader.GetString(1) '树上显示的是根节点名称

                '请根据你数据库字段的类型来决定是否用getstring或其它类型

                TreeView1.Nodes.Add(tree_root)

            End While

        Catch ex As Exception

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

        Finally

            myconnection.Close()

        End Try

        TreeView1.ExpandAll()

        TreeView1.Select()

    End Sub
 
好了,现在运行一下程序,你可以看到如图1所示的起始界面

 2.点击时加入子节点
对TreeView的点击,对于TreeView控件本身,并没有为哪一个级别的Node编写点击(选择)事件处理程序,而是把所有节点的点击事件都写入了一个AfterSelect事件中。因此,在编写点击加入子节点的程序之前,我们还必须编写一个查找点击的节点是哪一级节点的方法。

Public Function NodeLevel(ByVal n As TreeNode) As Byte

        '* 找出树中当前节点的级数

        Dim i As Byte = 1

        Dim m As String

        Do Until n.Parent Is Nothing

            n = n.Parent

            i += 1

        Loop

        Return i

End Function
通过这个函数,就可以很方便地得到节点的级别。现在我们可以放心地编写节点选择事件处理程序,以实现动态加载各级节点的子节点。
Private Sub TreeView1_AfterSelect
(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs)
 Handles TreeView1.AfterSelect

        Select Case NodeLevel(e.Node).ToString

            Case "1"

                If e.Node.GetNodeCount(False) = 0 Then

                    mycommand.CommandText = 
                    "select 第一级子节点编号,第一级子节点名称 
                    from 第一级子节点 where 根节点编号 ='" & e.Node.Tag & "'"

                    fill_treeleaf()

                End If

            Case "2"

                If e.Node.GetNodeCount(False) = 0 Then

                    mycommand.CommandText = 
                    "select 第二级子节点编号,第二级子节点名称 from 第二级子节点 
                    where 第一级子节点编号 ='" & e.Node.Tag & "'"

                    fill_treeleaf()

                End If

        End Select

End Sub

 

Public Sub fill_treeleaf()

        mycommand.Connection = myconnection

        Try

            myconnection.Open()

            Dim mysqlreader As OleDb.OleDbDataReader = mycommand.ExecuteReader

            While mysqlreader.Read()

                Dim tree_leaf As New TreeNode()

                tree_leaf.Tag = mysqlreader.GetString(0)

                tree_leaf.Text = mysqlreader.GetString(1)

                TreeView1.SelectedNode.Nodes.Add(tree_leaf)

            End While

        Catch ex As Exception

            MsgBox(ex.Message)

        Finally

            myconnection.Close()

        End Try

End Sub
本文作者提醒大家:请大家要熟悉Text与Tag的作用,在使用时会达到很好的效果。
 
不知道大家注意没有,本文出自于早些年,作者采用的后台数据源是传统的数据库形式,如果用现在流行的XML格式
作为后台数据源呢?效果会怎样呢?....我试过,用XML作为后台数据源更为方便,在运行速率上更好.改天我把代码
贴上来与大家一起分享.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值