【允许转载!但请注明出处!】
在.NET中,TreeView大体有三种实现方式。一、设置成静态的。即直接在控件中编辑节点设置属性即可。这种方式可以最简单快速的实现一个TreeView,但是不灵活,只适合于数据是一成不变的,一般没有人使用这种方式。本文不做重点介绍,不推荐使用。二、利用XML文件作为数据源实现。这种方式较第一种灵活,但是只适合有一个根的树。三、利用后台数据库动态添加数据实现。这种方式适合建立多根的树,比较灵活。实现起来也较为复杂。
接下来,让我们一个一个来看。
首先,看一下XML的方式怎样添加一个TreeView。
第一步,建立一个XML文件。
<?xml version="1.0" encoding="utf-8" ?>
<node title="父节点">
<node1 title="子节点1" url="Default.aspx">
<node11 title="子节点1-1" url="Default1.aspx"></node11>
</node1>
<node2 title="子节点2" url="Default2.aspx">
<node21 title="子节点2-1" url="Default21.aspx"></node21>
</node2>
<node3 title="子节点3" url="Default3.aspx">
<node31 title="子节点3-1" url="Default31.aspx"></node31>
</node3>
<node4 title="子节点4" url="Default4.aspx">
<node41 title="子节点4-1" url="Default41.aspx"></node41>
</node4>
</node>
然后添加XmlDataSource数据源,设置DataFile属性指向此XML文件。再将TreeView的DataSourceID的属性设置为刚刚建立的数据源的ID。接下来对TreeView进行数据绑定。在DataBindings编辑器中依次添加各个节点,并分别设置其TextField和NavigateUrlField属性值对应上面的XML文件的title和url。简单的绑定完成之后,这个树的添加就算完成了。
下面让我们来看一下怎样从数据库中动态添加数据到TreeView。实现方式上一般有两种。一是将所有数据一次性提取加载到TreeView,二是先加载根节点,当点击根节点时,再加载子节点数据。对于我个人来说,一般是使用第二种方式。当数据库数据量较为庞大时,第一种方式显示速度显然要慢很多。通常的做法都是先加载根节点数据,然后依次加载子节点和叶节点。而实现思路也有两种,迭代和循环。本人是用循环的方式来实现的。
先说一下数据库表和字段。表是作为类别表来设计的。一共三个字段cid(类别编号)、cname(类别名称)、parentid(父类编号)
第一步,在Default.aspx中添加一个TreeView。
<asp:TreeView ID="TreeView3" runat="server" Height="250px" ImageSet="Msdn" OnTreeNodeExpanded="TreeView3_TreeNodeExpanded"
ShowLines="True" Style="left: 405px; position: relative; top: -179px" Width="128px">
</asp:TreeView>
第二步,建立类别表类ProClass.cs存放数据。
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
/// <summary>
/// ProClass 的摘要说明
/// </summary>
public class ProClass
{
public ProClass()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
private string cid;
public string Cid
{
get { return cid; }
set { cid = value; }
}
private string cname;
public string Cname
{
get { return cname; }
set { cname = value; }
}
private string parentid;
public string Parentid
{
get { return parentid; }
set { parentid = value; }
}
}
第三步,建立数据访问类DBHelp.cs。
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Collections;
/// <summary>
/// DBHelp 的摘要说明
/// </summary>
public class DBHelp
{
public DBHelp()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
//取得所有父节点 parentid为零的是根节点
public static ArrayList GetTreeNodes()
{
ArrayList lst;
using(SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConStr"].ToString()))
{
con.Open();
string sql = "select * from ProClass where parentid = 0";
SqlCommand cmd = new SqlCommand(sql,con);
SqlDataReader dr = cmd.ExecuteReader();
lst = new ArrayList();
if (dr.HasRows)
{
while (dr.Read())
{
ProClass c = new ProClass();
c.Cid = dr["cid"].ToString();
c.Cname = dr["cname"].ToString();
c.Parentid = dr["parentid"].ToString();
lst.Add(c);
}
}
}
return lst;
}
//根据类别名称查询类别编号
public static int GetIdByName(string cname)
{
int cid = 0;
using (SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConStr"].ToString()))
{
con.Open();
string sql = "select cid from ProClass where cname='"+cname+"'";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
cid = Convert.ToInt32(dr[0]);
}
}
}
return cid;
}
//根据当前id号查询父类下是否有子类
public static ArrayList GetSonTreeNode(int id)
{
ArrayList lst;
using (SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConStr"].ToString()))
{
con.Open();
string sql = "select * from ProClass where parentid = "+id;
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader dr = cmd.ExecuteReader();
lst = new ArrayList();
if (dr.HasRows)
{
//如果能查询到 说明是子类别
while (dr.Read())
{
ProClass c = new ProClass();
c.Cid = dr["cid"].ToString();
c.Cname = dr["cname"].ToString();
c.Parentid = dr["parentid"].ToString();
lst.Add(c);
}
}
else
{
//否则 说明是父类别
return lst;
}
}
return lst;
}
}
第四步,在Default.aspx.cs文件中添加事件处理。
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
CreateDBTree();
}
}
TreeNode node;
private void CreateDBTree()
{
ArrayList list = DBHelp.GetTreeNodes();
foreach (ProClass pc in list)
{
node = new TreeNode(pc.Cname.ToString());
this.TreeView3.Nodes.Add(node);
}
}
//树节点展开事件
protected void TreeView3_TreeNodeExpanded(object sender, TreeNodeEventArgs e)
{
if (!IsPostBack)
{
string cname = e.Node.Text.ToString();
int cid = DBHelp.GetIdByName(cname);
ArrayList list = DBHelp.GetSonTreeNode(cid);
foreach (ProClass p in list)
{
node = new TreeNode(p.Cname);
e.Node.ChildNodes.Add(node);
e.Node.Expanded = false; //初次显示成闭合状态
}
}
}
}
另:添加节点跳转地址:
可将第四步修改为:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
CreateDBTree();
}
}
static TreeNode node;
string turnUrl = "Default2.aspx";
private void CreateDBTree()
{
ArrayList list = DBHelp.GetTreeNodes();
foreach (ProClass pc in list)
{
node = new TreeNode(pc.Cname.ToString());
this.TreeView3.Nodes.Add(node);
}
}
protected void TreeView3_TreeNodeExpanded(object sender, TreeNodeEventArgs e)
{
string cname = e.Node.Text.ToString();
int cid = DBHelp.GetIdByName(cname);
if (!IsPostBack)
{
ArrayList list = DBHelp.GetSonTreeNode(cid);
foreach (ProClass p in list)
{
TreeNode node1 = new TreeNode(p.Cname);
e.Node.ChildNodes.Add(node1);
//e.Node.Expanded = false; //初次显示成闭合状态
}
//添加所有子节点的URL地址
if (e.Node.ChildNodes.Count > 0)
{
for (int i = 0; i < e.Node.ChildNodes.Count; i++)
{
e.Node.ChildNodes[i].NavigateUrl = turnUrl + "?cid=" + DBHelp.GetIdByName(e.Node.ChildNodes[i].Text.ToString());
}
}
//添加当前节点的URL地址
e.Node.NavigateUrl = turnUrl + "?cid=" + cid;
}
}
}