最近的一个项目要用到树形结构,所以找了很多关于树形结构的资料,感觉有着各种各样的问题。
现在把找到的比较实用的且比较简单和大家分享一下。
项目是在web页面下,通过数据库中表tbtree中的内容来实现树形结构的无限添加。
开发环境是vs2005,数据库是SQL SERVER2005
先在数据库test中创建表tbtree并插入数据
create table tbtree
(
ID int primary key,
Name nvarchar(50),
ParentID int
)
insert into tbtree(ID,Name,ParentId)values(1,'A',0);
insert into tbtree(ID,Name,ParentId)values(2,'B',0);
insert into tbtree(ID,Name,ParentId)values(3,'C',0);
insert into tbtree(ID,Name,ParentId)values(4,'A1',1);
insert into tbtree(ID,Name,ParentId)values(5,'B1',2);
insert into tbtree(ID,Name,ParentId)values(6,'C1',3);
insert into tbtree(ID,Name,ParentId)values(7,'A11',4);
insert into tbtree(ID,Name,ParentId)values(8,'A12',4);
insert into tbtree(ID,Name,ParentId)values(9,'A13',4);
insert into tbtree(ID,Name,ParentId)values(10,'B11',5);
insert into tbtree(ID,Name,ParentId)values(11,'B12',5);
insert into tbtree(ID,Name,ParentId)values(12,'B13',5);
insert into tbtree(ID,Name,ParentId)values(13,'C11',6);
insert into tbtree(ID,Name,ParentId)values(14,'C12',6);
insert into tbtree(ID,Name,ParentId)values(15,'C13',6);
insert into tbtree(ID,Name,ParentId)values(16,'A111',7);
insert into tbtree(ID,Name,ParentId)values(17,'A112',7);
insert into tbtree(ID,Name,ParentId)values(18,'A113',7);
insert into tbtree(ID,Name,ParentId)values(19,'A1111',16);
这样表就有了,可以进行调用了
在vs2005中添加一个新项Tree.aspx
代码如下(其中还用到javascript来实现无刷新的选中父节点,子节点同时选中)
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Tree.aspx.cs" Inherits="Tree" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>无标题页</title>
<script type="text/javascript">
function getcheck()
{
var o = window.event.srcElement;
if (o.tagName == "INPUT" && o.type == "checkbox") //点击treeview的checkbox是触发
{
var d=o.id;//获得当前checkbox的id;
var e= d.replace("CheckBox","Nodes");//通过查看脚本信息,获得包含所有子节点div的id
var div= window.document.getElementById(e);//获得div对象
if(div!=null) //如果不为空则表示,存在子节点
{
var check=div.getElementsByTagName("INPUT");//获得div中所有的已input开始的标记
for(i=0;i<check.length;i++)
{
if(check[i].type=="checkbox") //如果是checkbox
{
check[i].checked=o.checked;//字节点的状态和父节点的状态相同,即达到全选
}
}
}
else //点子节点的时候,使父节点的状态改变,即不为全选
{
//处理父节点
var divid=o.parentElement.parentElement.parentElement.parentElement.parentElement; //子节点所在的div
var id= divid.id.replace("Nodes","CheckBox"); //获得根节点的id
var checkbox=divid.getElementsByTagName("INPUT"); //获取所有子节点数
var s=0;
for(i=0;i<checkbox.length;i++)
{
if(checkbox[i].checked) //判断有多少子节点被选中
{
s++;
}
}
if(s==checkbox.length) //如果全部选中 或者 选择的是另外一个根节点的子节点 ,
{ // 则开始的根节点的状态仍然为选中状态
window.document.getElementById(id).checked=true;
}
else
{ //否则为没选中状态
window.document.getElementById(id).checked=false;
}
}
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TreeView ID="TreeView1" runat="server" ShowCheckBoxes="All">
</asp:TreeView>
</div>
</form>
</body>
</html>
后台Tree.aspx.cs代码如下
using System;
using System.Data;
using System.Configuration;
using System.Collections;
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;
public partial class Tree : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
bindtree();
TreeView1.Attributes.Add("onclick", "getcheck()");
}
}
void bindtree()
{
// 定义数据库连接
SqlConnection CN = new SqlConnection();
try
{
//初始化连接字符串
CN.ConnectionString = "database=test;server=.;user id=sa;Password=sa;";
CN.Open();
SqlDataAdapter adp = new SqlDataAdapter("select * from tbtree", CN);
DataSet ds = new DataSet();
adp.Fill(ds);
this.ViewState["ds"] = ds;
}
catch (Exception ex)
{
//Session["Error"] = ex.ToString();
//Response.Redirect("error.aspx"); //?跳转程序的公共错误处理页面
}
finally
{
CN.Close();
}
//调用递归函数,完成树形结构的生成
AddTree(0, (TreeNode)null);
}
public void AddTree(int ParentID, TreeNode pNode)
{
DataSet ds = (DataSet)this.ViewState["ds"];
DataView dvTree = new DataView(ds.Tables[0]);
//过滤ParentID,得到当前的所有子节点
dvTree.RowFilter = "ParentID = " + ParentID;
foreach (DataRowView Row in dvTree)
{
TreeNode Node = new TreeNode();
if (pNode == null)
{ //添加根节点
Node.Text = Row["Name"].ToString();
Node.Value = Row["ID"].ToString();
TreeView1.Nodes.Add(Node);
Node.Expanded = false;
AddTree(Int32.Parse(Row["ID"].ToString()), Node); //再次递归
}
else
{ //?添加当前节点的子节点
Node.Text = Row["Name"].ToString();
Node.Value = Row["ID"].ToString();
pNode.ChildNodes.Add(Node);
Node.Expanded = false;
AddTree(Int32.Parse(Row["ID"].ToString()), Node); //再次递归
}
}
}
}