概述

TreeView是一个重要的控件,无论是在VB.NET,C# 还是VB、Delphi等各种语言中,都充当了导航器的作用。在实际工作中,很多情况下需要将TreeView与数据库进行连接,以填充其节点。在Windows Form和Web Form中,我们可以用TreeView来显示树形结构,如显示目录树、显示地区、分类显示商品等。可以说,在大部分软件的开发中,TreeView都是一个不可缺少的展示控件。因此,树形结构的设计就成了软件开发人员一个永恒的话题。
树形结构的展示方式
树形结构的展示一般来讲有三种方式:
1.界面设计时在TreeView设计器或者代码中直接填充TreeView控件。
2.从XML文件中建立树形结构。
3.从数据库中得到数据,建立树形结构。
第一种方式是最简单的,这种方式主要用于树形结构一般没有变化的应用程序,在设计时就固定一颗树。当然,在设计时固定了树的结构,以后要想修改、增加、删除树的节点,就必须修改源程序。所有不利于扩展。
第二种方式从XML文件中提取,由于XML本身就是树形结构的,微软提供的文档对象模型DOM 可以方便的读取、操作和修改 XML 文档。在.NET中,应用System.Xml类可以方便地将XML文件加载到TreeView控件中,微软的MSDN也提供了实例,此处就不再多说。
第三种方式,树形结构的数据,从数据库中获得。一般来讲,我们的应用程序多数是基于数据库的。采用这种方式,增加、修改、删除一颗树的节点很方便,只要操作数据库中的数据就可以了。而且,这种方式可以和数据库中的其它表做关联、查询和汇总,通过设计视图或存储过程,很容易查询出你想要的相关数据。下面,我们主要讨论这种方式的设计和实现。

数据库设计

首先,我们在SQL SERVER 2000里建立一个表tbTree,表的结构设计如下:
列名    数据类型    描述        长度    主键
ID    Int    节点编号        4    是
ParentID    Int    父节点编号        4    
ConText    Nvarchar    我们要显示的节点内容    50    

在SQL SERVER 2000中建表的脚本:

  1. CREATE TABLE [dbo].[tbTree] (  
  2.     [ID] [int] IDENTITY (1, 1) NOT NULL ,  
  3.     [Context] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,  
  4.     [ParentID] [intNULL   
  5. ON [PRIMARY


在表中添加如下记录:

  1. SET IDENTITY_INSERT tbtree ON 
  2. insert tbtree (ID,Context,ParentID)  values ( 1,'中国',0)  
  3. insert tbtree (ID,Context,ParentID)  values ( 2,'北京',11)  
  4. insert tbtree (ID,Context,ParentID)  values ( 3,'天津',11)  
  5. insert tbtree (ID,Context,ParentID)  values ( 4,'河北省',1)  
  6. insert tbtree (ID,Context,ParentID)  values ( 5,'广东省',1)  
  7. insert tbtree (ID,Context,ParentID)  values ( 6,'广州',5)  
  8. insert tbtree (ID,Context,ParentID)  values ( 7,'四川省',1)  
  9. insert tbtree (ID,Context,ParentID)  values ( 8,'成都',7)  
  10. insert tbtree (ID,Context,ParentID)  values ( 9,'深圳',5)  
  11. insert tbtree (ID,Context,ParentID)  values ( 10,'石家庄',4)  
  12. insert tbtree (ID,Context,ParentID)  values ( 11,'辽宁省',1)  
  13. insert tbtree (ID,Context,ParentID)  values ( 12,'大连',11)  
  14. insert tbtree (ID,Context,ParentID)  values ( 13,'上海',1)  
  15. insert tbtree (ID,Context,ParentID)  values ( 14,'天河软件园',6)  
  16. insert tbtree (ID,Context,ParentID)  values ( 15,'汕头',5)  
  17. SET IDENTITY_INSERT tbtree off 


按此在新窗口打开图片
下载地址
http://msdn.microsoft.com/downloads/samples/internet/ASP_DOT_NET_ServerControls/WebControls/default.asp
安装后,通过“自定义工具箱”->“.net框架组件”把TreeView添加到工具箱里。
新建一个项目,选择Visual Basic.Net 工程Asp.net Web应用程序,在页面上拖画一个TreeView控件。

Html页:

  1. <%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %> 
  2. <%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="Tree.WebForm1"%> 
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
  4. <HTML> 
  5. <HEAD> 
  6. <title>WebForm1</title> 
  7. <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.0"> 
  8. <meta name="CODE_LANGUAGE" content="Visual Basic 7.0"> 
  9. <meta name="vs_defaultClientScript" content="JavaScript"> 
  10. <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> 
  11. </HEAD> 
  12. <body MS_POSITIONING="GridLayout"> 
  13. <form id="Form1" method="post" runat="server"> 
  14. <FONT face="宋体"> 
  15. <iewc:TreeView id="TreeView1" style="Z-INDEX: 101; LEFT: 39px; TOP: 68px" runat="server"></iewc:TreeView></FONT> 
  16. </form> 
  17. </body> 
  18. </HTML> 


后台代码:

  1.     Private Sub Page_Load(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles MyBase.Load  
  2.         Dim ds As New DataSet()  
  3.         Dim CN As New SqlConnection()  
  4.         Try 
  5.             '初始化连接字符串  
  6.             CN.ConnectionString =   
  7.             "data source=pmserver;initial catalog=Benchmark;persist security info=False;user id=sa;Password=sa;" 
  8.             CN.Open()  
  9.             Dim adp As SqlDataAdapter = New SqlDataAdapter("select * from tbTree", CN)  
  10.             adp.Fill(ds)  
  11.             Me.ViewState("ds") = ds  
  12.         Catch ex As Exception  
  13. #If DEBUG Then  
  14.             Session("Error") = ex.ToString()  
  15.             Response.Redirect("error.aspx")        '̀跳转程序的公共错误处理页面  
  16. #End If  
  17.         Finally 
  18.             '关闭连接  
  19.             CN.Close()  
  20.         End Try 
  21.         '调用递归函数,完成树形结构的生成  
  22.         AddTree(0, Nothing)  
  23.     End Sub 
  24.  
  25.     '递归添加树的节点  
  26.     Private Sub AddTree(ByVal ParentID As IntegerByVal pNode As TreeNode)  
  27.         Dim ds As DataSet  
  28.         ds = Me.ViewState("ds")  
  29.         Dim dvTree As New DataView()  
  30.         dvTree = New DataView(ds.Tables(0))  
  31.         '过滤ParentID,得到当前的所有子节点  
  32.         dvTree.RowFilter = "PARENTID = " + ParentID.ToString  
  33.  
  34.         Dim Row As DataRowView  
  35.         For Each Row In dvTree  
  36.             Dim Node As New TreeNode()  
  37.             If pNode Is Nothing Then  '判断是否根节点  
  38.                 '添加根节点  
  39.                 Node.Text = Row("ConText").ToString()  
  40.                 TreeView1.Nodes.Add(Node)  
  41.                 Node.Expanded = True 
  42.                 '再次递归  
  43.                 AddTree(Int32.Parse(Row("ID").ToString()), Node)  
  44.             Else 
  45.                 '̀添加当前节点的子节点  
  46.                 Node.Text = Row("ConText").ToString()  
  47.                 pNode.Nodes.Add(Node)  
  48.                 Node.Expanded = True 
  49.                 '再次递归  
  50.                 AddTree(Int32.Parse(Row("ID").ToString()), Node)  
  51.             End If 
  52.         Next 
  53.     End Sub 


C#版本:

  1. using System;  
  2. using System.Collections;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Web;  
  7. using System.Web.SessionState;  
  8. using System.Web.UI;  
  9. using System.Web.UI.WebControls;  
  10. using System.Web.UI.HtmlControls;  
  11. using Microsoft.Web.UI.WebControls;  
  12. using System.Data.SqlClient;  
  13. namespace TreeCS  
  14. {  
  15.     ///   
  16.     /// WebForm1 的摘要说明  
  17.     ///   
  18.     public class WebForm1 : System.Web.UI.Page  
  19.     {  
  20.         protected Microsoft.Web.UI.WebControls.TreeView TreeView1;  
  21.       
  22.         private void Page_Load(object sender, System.EventArgs e)  
  23.         {  
  24.             // 定义数据库连接  
  25.             SqlConnection CN = new SqlConnection();  
  26.             try   
  27.             {  
  28.                 //初始化连接字符串  
  29.                 CN.ConnectionString=  
  30.                 "data source=pmserver;initial catalog=Benchmark;persist security info=False;user id=sa;Password=sa;";  
  31.                 CN.Open();  
  32.  
  33.                 SqlDataAdapter adp = new SqlDataAdapter("select * from tbTree",CN);  
  34.                 DataSet ds=new DataSet();  
  35.                 adp.Fill(ds);  
  36.                 this.ViewState["ds"]=ds;   
  37.             }  
  38.             catch (Exception ex)  
  39.             {  
  40.                 Session["Error"] = ex.ToString();  
  41.                 Response.Redirect("error.aspx");       //̀跳转程序的公共错误处理页面  
  42.             }  
  43.             finally   
  44.             {  
  45.                 CN.Close();  
  46.             }  
  47.             //调用递归函数,完成树形结构的生成  
  48.             AddTree(0, (TreeNode)null);  
  49.         }  
  50.  
  51.         //递归添加树的节点  
  52.         public void AddTree(int ParentID,TreeNode pNode)   
  53.         {  
  54.             DataSet ds=(DataSet) this.ViewState["ds"];   
  55.             DataView dvTree = new DataView(ds.Tables[0]);  
  56.             //过滤ParentID,得到当前的所有子节点  
  57.             dvTree.RowFilter =  "[PARENTID] = " + ParentID;  
  58.  
  59.             foreach(DataRowView Row in dvTree)   
  60.             {  
  61.                 TreeNode Node=new TreeNode() ;  
  62.                 if(pNode == null)   
  63.                 {    //添加根节点  
  64.                     Node.Text = Row["ConText"].ToString();  
  65.                     TreeView1.Nodes.Add(Node);  
  66.                     Node.Expanded=true;  
  67.                     AddTree(Int32.Parse(Row["ID"].ToString()), Node);    //再次递归  
  68.                 }   
  69.                 else   
  70.                 {   //̀添加当前节点的子节点  
  71.                     Node.Text = Row["ConText"].ToString();  
  72.                     pNode.Nodes.Add(Node);  
  73.                     Node.Expanded = true;  
  74.                     AddTree(Int32.Parse(Row["ID"].ToString()),Node);     //再次递归  
  75.                 }  
  76.             }                     
  77.         }              
  78.  
  79.         #region Web Form Designer generated code  
  80.         override protected void OnInit(EventArgs e)  
  81.         {  
  82.             //  
  83.             // CODEGEN该调用是 ASP.NET Web 窗体设计器所必需的。  
  84.             //  
  85.             InitializeComponent();  
  86.             base.OnInit(e);  
  87.         }  
  88.           
  89.         /// <summary>  
  90.         ///设计器支持所需的方法 - 不要使用代码编辑器修改  
  91.         /// 此方法的内容  
  92.         /// </summary>  
  93.         private void InitializeComponent()  
  94.         {      
  95.             this.Load += new System.EventHandler(this.Page_Load);  
  96.  
  97.         }  
  98.         #endregion  
  99.     }  


后记:请读者自行修改程序中的连接字符串设置。
附:相关微软MSDN文档,包括在VB6和.NET中从XML建立树形结构 
http://support.microsoft.com/default.aspx?kbid=311318
http://support.microsoft.com/default.aspx?kbid=308063
http://support.microsoft.com/default.aspx?kbid=317597
http://support.microsoft.com/default.aspx?kbid=244954

本日志由 flyinweb 于 2009-06-21 20:51:26 发表到 DotNet专栏 中,目前已经被浏览 3821 次,评论 0 次;

作者添加了以下标签: 树形结构