(无限级、递归)DropDownList显示树形分类
简单无限级表结构:id,name,pid。
本篇将展示如何在DropDownList控件显示一个漂亮的树结构。
1.以下我们建立无限级树的表结构
--星辰变的修真等级表
CREATE TABLE XianMO
(
XianMoID INT NOT NULL ,
XianMoLevel VARCHAR(50) NOT NULL DEFAULT(''),
XianMoParentID INT NOT NULL DEFAULT(0)
)
GO
--索引
CREATE NONCLUSTERED INDEX IX_XianMo ON XianMo(XianMoID)
GO
CREATE TABLE XianMO
(
XianMoID INT NOT NULL ,
XianMoLevel VARCHAR(50) NOT NULL DEFAULT(''),
XianMoParentID INT NOT NULL DEFAULT(0)
)
GO
--索引
CREATE NONCLUSTERED INDEX IX_XianMo ON XianMo(XianMoID)
GO
2.有了表结构,我们将添加一些数据。^_^
INSERT INTO XianMo(XianMoID,XianMoLevel,XianMoParentID)
SELECT 1,'凡人',0
UNION ALL SELECT 2,'修真者',0
UNION ALL SELECT 3,'后天境界',2
UNION ALL SELECT 4,'先天境界(四九小天劫)',2
UNION ALL SELECT 5,'金丹期',2
UNION ALL SELECT 6,'元婴期(六九大天劫)',2
UNION ALL SELECT 7,'洞虚期',2
UNION ALL SELECT 8,'空冥期',2
UNION ALL SELECT 9,'渡劫期(九九重劫)',2
UNION ALL SELECT 10,'大乘期',2
UNION ALL SELECT 11,'仙人',0
UNION ALL SELECT 12,'散仙',11
UNION ALL SELECT 13,'天仙',11
UNION ALL SELECT 14,'金仙',11
UNION ALL SELECT 15,'玄仙',11
UNION ALL SELECT 16,'仙帝',11
UNION ALL SELECT 17,'神人',0
UNION ALL SELECT 18,'下级神人',17
UNION ALL SELECT 19,'中级神人',17
UNION ALL SELECT 20,'上级神人',17
UNION ALL SELECT 21,'天神',0
UNION ALL SELECT 22,'下部天神',21
UNION ALL SELECT 23,'中部天神',21
UNION ALL SELECT 24,'上部天神',21
UNION ALL SELECT 25,'神王',0
UNION ALL SELECT 26,'天尊',0
UNION ALL SELECT 27,'鸿蒙',0
GO
UNION ALL SELECT 2,'修真者',0
UNION ALL SELECT 3,'后天境界',2
UNION ALL SELECT 4,'先天境界(四九小天劫)',2
UNION ALL SELECT 5,'金丹期',2
UNION ALL SELECT 6,'元婴期(六九大天劫)',2
UNION ALL SELECT 7,'洞虚期',2
UNION ALL SELECT 8,'空冥期',2
UNION ALL SELECT 9,'渡劫期(九九重劫)',2
UNION ALL SELECT 10,'大乘期',2
UNION ALL SELECT 11,'仙人',0
UNION ALL SELECT 12,'散仙',11
UNION ALL SELECT 13,'天仙',11
UNION ALL SELECT 14,'金仙',11
UNION ALL SELECT 15,'玄仙',11
UNION ALL SELECT 16,'仙帝',11
UNION ALL SELECT 17,'神人',0
UNION ALL SELECT 18,'下级神人',17
UNION ALL SELECT 19,'中级神人',17
UNION ALL SELECT 20,'上级神人',17
UNION ALL SELECT 21,'天神',0
UNION ALL SELECT 22,'下部天神',21
UNION ALL SELECT 23,'中部天神',21
UNION ALL SELECT 24,'上部天神',21
UNION ALL SELECT 25,'神王',0
UNION ALL SELECT 26,'天尊',0
UNION ALL SELECT 27,'鸿蒙',0
GO
3.创建一个存储过程,我们在这里就已经把树结构完整的展示出来了。
-- =============================================
-- Author: Star Studio
-- Create date: 2010-09-10
-- Description: Tree In DropDownList
-- =============================================
ALTER PROCEDURE[dbo].[GetTree]
@tableName VARCHAR(100),--表名
@idName VARCHAR(100),--id字段名
@className VARCHAR(100),--class字段名
@pidName VARCHAR(100),--父id字段名
@pidValue INT,--指定此次构造树的根节点
@idExcepted INT--此次构造的树,将排除显示的节点及其子节点。这在修改节点的父关系时很有用。你不可以指定某节点的老爸是自己或自己的儿子吧。所以这时就要屏蔽掉自己及子节点
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Level INT
DECLARE @strTree VARCHAR(8000)
DECLARE @t TABLE(id INT,class VARCHAR(100), pid INT)
DECLARE @ttemp TABLE(id INT,class VARCHAR(100),pid INT,lev INT,codeid VARCHAR(8000))
SET @Level=0
SET @strTree='┊┈┈'
INSERT INTO @t EXEC('SELECT '+@idName+' AS id,'+@className+' AS class,'+@pidName+' AS pid FROM '+@tableName+'')
-- Author: Star Studio
-- Create date: 2010-09-10
-- Description: Tree In DropDownList
-- =============================================
ALTER PROCEDURE[dbo].[GetTree]
@tableName VARCHAR(100),--表名
@idName VARCHAR(100),--id字段名
@className VARCHAR(100),--class字段名
@pidName VARCHAR(100),--父id字段名
@pidValue INT,--指定此次构造树的根节点
@idExcepted INT--此次构造的树,将排除显示的节点及其子节点。这在修改节点的父关系时很有用。你不可以指定某节点的老爸是自己或自己的儿子吧。所以这时就要屏蔽掉自己及子节点
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Level INT
DECLARE @strTree VARCHAR(8000)
DECLARE @t TABLE(id INT,class VARCHAR(100), pid INT)
DECLARE @ttemp TABLE(id INT,class VARCHAR(100),pid INT,lev INT,codeid VARCHAR(8000))
SET @Level=0
SET @strTree='┊┈┈'
INSERT INTO @t EXEC('SELECT '+@idName+' AS id,'+@className+' AS class,'+@pidName+' AS pid FROM '+@tableName+'')
--排除的节点有可能是根节点
INSERT INTO @ttemp SELECT id,@strTree+class,pid,@level,right(10000+id,4) FROM@tWHERE pid=@pidValueAND id<>@idExcepted
WHILE @@rowcount>0--一层层递归构造排序字段codeid
BEGIN
SET @strTree=replace(@strTree,'┈','')
SET @strTree=@strTree+'┊┈┈'
SET @level=@level+1
IF(@idExcepted=0)
BEGIN
INSERT @ttemp SELECT a.id,@strTree+a.class,a.pid,@level,b.codeid+right(10000+a.id,4) FROM@t a,@ttemp b
WHERE a.pid=b.id AND b.lev=@level-1
END
ELSE
BEGIN
INSERT INTO @ttemp SELECT id,@strTree+class,pid,@level,right(10000+id,4) FROM@tWHERE pid=@pidValueAND id<>@idExcepted
WHILE @@rowcount>0--一层层递归构造排序字段codeid
BEGIN
SET @strTree=replace(@strTree,'┈','')
SET @strTree=@strTree+'┊┈┈'
SET @level=@level+1
IF(@idExcepted=0)
BEGIN
INSERT @ttemp SELECT a.id,@strTree+a.class,a.pid,@level,b.codeid+right(10000+a.id,4) FROM@t a,@ttemp b
WHERE a.pid=b.id AND b.lev=@level-1
END
ELSE
BEGIN
--排除的节点是某个子节点
INSERT @ttemp SELECT a.id,@strTree+a.class,a.pid,@level,b.codeid+right(10000+a.id,4) FROM@t a,@ttemp b
WHERE a.pid=b.id AND b.lev=@level-1AND b.id<>@idExcepted
END
END
INSERT @ttemp SELECT a.id,@strTree+a.class,a.pid,@level,b.codeid+right(10000+a.id,4) FROM@t a,@ttemp b
WHERE a.pid=b.id AND b.lev=@level-1AND b.id<>@idExcepted
END
END
--只要按codeid排列结果集,就能得到正确完整的树结构
SELECT a.id,a.pid,b.class,b.lev,b.codeid FROM @t a,@ttemp b WHERE a.id=b.id ORDERBY b.codeid
END
GO
--事例演示
exec gettree 'XianMo','xianmoid','xianmolevel','xianmoparentid',0,11
SELECT a.id,a.pid,b.class,b.lev,b.codeid FROM @t a,@ttemp b WHERE a.id=b.id ORDERBY b.codeid
END
GO
--事例演示
exec gettree 'XianMo','xianmoid','xianmolevel','xianmoparentid',0,11
演示事例一及其结果集:
--不排除任何一个节点
exec gettree 'XianMo','xianmoid','xianmolevel','xianmoparentid',0,0
exec gettree 'XianMo','xianmoid','xianmolevel','xianmoparentid',0,0
演示事例二及其结果集:
--排除仙人节点
exec gettree 'XianMo','xianmoid','xianmolevel','xianmoparentid',0,11
exec gettree 'XianMo','xianmoid','xianmolevel','xianmoparentid',0,11
看了以上两图,你应该知道,该存储过程的原理是通过递归构造一个排序字段codeid,然后根据codeid排序就得到完整的属性排列了。
4.接下来只要把数据放入DropDownList,就能显示一颗漂亮的树了。
<!--DropDownListTree.aspx-->
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DropDownListTree.aspx.cs" Inherits="_Default"%>
<!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>DropDownList显示树结构</title>
<style type="text/css">
#TreeBlock{width:200px;}
#TreeBlock #ddlXianMoTree{background-color:#FFAA2B; }
</style>
</head>
<body>
<form id="form1" runat="server">
<div id="TreeBlock">
<asp:DropDownList ID="ddlXianMoTree" runat="server"></asp:DropDownList>
</div>
</form>
</body>
</html>
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DropDownListTree.aspx.cs" Inherits="_Default"%>
<!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>DropDownList显示树结构</title>
<style type="text/css">
#TreeBlock{width:200px;}
#TreeBlock #ddlXianMoTree{background-color:#FFAA2B; }
</style>
</head>
<body>
<form id="form1" runat="server">
<div id="TreeBlock">
<asp:DropDownList ID="ddlXianMoTree" runat="server"></asp:DropDownList>
</div>
</form>
</body>
</html>
//DropDownListTree.aspx.cs
using System;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Data.SqlClient;
using WnetSoft.Common.DBHelper;
publicpartialclass _Default : System.Web.UI.Page
{
protectedvoid Page_Load(object sender, EventArgs e)
{
SqlParameter[] SqlParamList ={
SqlHelper.MakeInParam("@tableName",SqlDbType.VarChar,100,"XianMo"),
SqlHelper.MakeInParam("@idName",SqlDbType.VarChar,100,"XianMoID"),
SqlHelper.MakeInParam("@className",SqlDbType.VarChar,100,"XianMoLevel"),
SqlHelper.MakeInParam("@pidName",SqlDbType.VarChar,100,"XianMoParentID"),
SqlHelper.MakeInParam("@pidValue",SqlDbType.Int,10,0),
SqlHelper.MakeInParam("@idExcepted",SqlDbType.Int,10,0)
};
ddlXianMoTree.DataSource = SqlHelper.ExecuteReader(SqlHelper.connString, CommandType.StoredProcedure, "GetTree", SqlParamList);
ddlXianMoTree.DataTextField ="class";
ddlXianMoTree.DataValueField ="id";
ddlXianMoTree.DataBind();
ddlXianMoTree.Items.Insert(0, new ListItem("--根节点--", "0"));
}
}
using System;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Data.SqlClient;
using WnetSoft.Common.DBHelper;
publicpartialclass _Default : System.Web.UI.Page
{
protectedvoid Page_Load(object sender, EventArgs e)
{
SqlParameter[] SqlParamList ={
SqlHelper.MakeInParam("@tableName",SqlDbType.VarChar,100,"XianMo"),
SqlHelper.MakeInParam("@idName",SqlDbType.VarChar,100,"XianMoID"),
SqlHelper.MakeInParam("@className",SqlDbType.VarChar,100,"XianMoLevel"),
SqlHelper.MakeInParam("@pidName",SqlDbType.VarChar,100,"XianMoParentID"),
SqlHelper.MakeInParam("@pidValue",SqlDbType.Int,10,0),
SqlHelper.MakeInParam("@idExcepted",SqlDbType.Int,10,0)
};
ddlXianMoTree.DataSource = SqlHelper.ExecuteReader(SqlHelper.connString, CommandType.StoredProcedure, "GetTree", SqlParamList);
ddlXianMoTree.DataTextField ="class";
ddlXianMoTree.DataValueField ="id";
ddlXianMoTree.DataBind();
ddlXianMoTree.Items.Insert(0, new ListItem("--根节点--", "0"));
}
}
有点遗憾是,我传入XianMoID,XianMoLevel字段,返回的结果是id,class字段。
以上就是本篇内容。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)