asp生成树状的方法
- 格式:doc
- 大小:27.50 KB
- 文档页数:3
/script > < head >< /head > < body id=">
在中构建树形目录
彭凤梅
【期刊名称】《科技广场》
【年(卷),期】2005(000)005
【摘要】在上网浏览时,有时会看到一些网站在左边采用类似资源管理器的树形结构,在树形结构中单击,则在右边显示内容或者跳转到其它的页面,层次清晰,方便快捷.以前,在Web页面中如果想使用树形控件的话,往往会有些麻烦,有时甚至要自己写代码来达到用树形列表显示数据的目的.然而,在中,我们可以很方便地使用由微软提供的Internet Explorer Web Controls控件来实现树形列表.本文主要介绍在中利用服务器控件Treeview构建目录树的静态和动态方法,并且描述了采用先序遍历的方法动态构建树形目录.
【总页数】4页(P66-69)
【作者】彭凤梅
【作者单位】东华理工学院物理系,抚州,344000
【正文语种】中文
【中图分类】TP311.52
【相关文献】
1.在中动态生成目录树 [J], 马红春;邱小湖
2.基于环境的树形图的设计与实现 [J], 杨帆
3.在网页中实现菜单和树形结构目录 [J], 李新;杨章远
4.用C语言实现对树形目录结构下不可视目录名的自动改名 [J], 秦相林
5.浅析树形控件在中的使用 [J], 刘雄军;宁云智
因版权原因,仅展示原文概要,查看原文内容请购买。
在中开发树状结构
摘要:
在网页中用树状结构显示数据既清晰又简单,用户非常需要。
本文从实际应用的角度,介绍了在ASP中使用TreeView控件来创建树状结构的几种具体方法,可以方便地建立静、动态树状结构,较好地解决了树状结构在生成无限层次不定数量节点时非常困难而且容易出错的问题。
关键字:
Treeview控件、命名空间、静态树、动态树
一、引言
在网页开发工具ASP的应用中,用户经常希望用树状控件来显示分类或层次数据,这样既简单又直观,但是ASP本身没有提供此控件。
当然程序员可以用ImageButton和Label等组成的用户控件和XML、XSL语言自己进行编写,它们可以显示有限层次少量节点的树状,但要生成无限层次不定数量的节点时就难以实现并且非常容易出错。
作者通过对Microsoft下TreeView控件大量的实际应用,可以非常方便地实现任何类型的树状结构,较好地解决了上述问题。
二、安装TreeView控件、导入命名空间
在你的Web程序使用TreeView控件之前,首先必须下载InterExplorerWebBrowercontrols到你的开发机器上,然后导入命名空间。
可访问以下网址下载:
asp/ControlGallery/default.aspx?Category=38。
VSFlexGrid是一种强大的控件,它可以用来创建树形结构数据。
以下是一个简单的VSFlexGrid 树型实例:首先,在VB6中创建一个新的窗体,并添加VSFlexGrid控件。
双击控件打开代码编辑器,在Form_Load事件中添加如下代码:Private Sub Form_Load()' 设置网格属性VsFlexGrid1.Rows = 1 ' 初始化行数为1VsFlexGrid1.Cols = 3 ' 初始化列数为3VsFlexGrid1.FixedCols = 0 ' 固定列数为0VsFlexGrid1.BorderStyle = flexBorderNone ' 去掉边框线VsFlexGrid1.TreeColumn = 0 ' 第1列为树形结构' 设置第1列为树形结构VsFlexGrid1.Cols(0).CellType = flexCTTreeButtonVsFlexGrid1.Cols(0).DataType = flexDTBooleanVsFlexGrid1.Cols(0).Width = 400 ' 设置宽度为400' 添加数据VsFlexGrid1.AddItem "Node 1", 0, 1VsFlexGrid1.AddItem "Subnode 1.1", 1, 2VsFlexGrid1.AddItem "Subnode 1.2", 1, 2VsFlexGrid1.AddItem "Node 2", 0, 1VsFlexGrid1.AddItem "Subnode 2.1", 4, 2VsFlexGrid1.AddItem "Subnode 2.2", 4, 2End Sub运行程序,你会看到一个带有树形结构的VSFlexGrid表格。
+TreeView实现树状结构
李霞
【期刊名称】《运城学院学报》
【年(卷),期】2006(24)2
【摘要】在制作课程目录、新闻分类、后台管理等网页时,如果使用树状结构来显示数据,不仅结构清晰,而且方便用户访问.从实际应用的角度,介绍了在中如何结合TreeView控件访问SQL Server2000来创建树状结构,并且较好地解决了树状结构在生成无限层次不定数量节点时非常困难而且容易出错的问题.
【总页数】2页(P49-50)
【作者】李霞
【作者单位】山西大学,计算机与信息技术学院,山西,太原,030006;运城学院,公共计算机教学部,山西,运城,044000
【正文语种】中文
【中图分类】TP32
【相关文献】
1.关系数据库的树状结构及其在labview中的实现方法 [J], 丁进成
2.故障知识库中树状结构的表示与实现 [J], 史永胜;宋云雪
3.基于知识点树状结构的超声诊断参考系统设计与实现 [J], 傅建群;何嘉辉;庞熙楹;姜惠悦;苏洪安
4.基于树状结构的南京大学文科“读、写、议”系统:设计与实现 [J], 成颖;孙建军;
郑建明
5.基于树状结构的高速公路路网扩展及收费清分实现 [J], 杜海宁;张毅;宋靖雁因版权原因,仅展示原文概要,查看原文内容请购买。
使⽤ASP实现⽹站的“⽬录树”管理的代码使⽤ASP实现⽹站的⽬录树数据库结构(共使⽤了两个表)1。
tblCategory字段名类型Root binary 说明树关或开(⽬录的根)ID ⾃动编号关键字Sort integer 识别该字段内容的整数(如果root是开状态sort为0)表⽰显⽰的⽬录的顺序Name text(255)可以包含html中的标识符HREF text(255) 允许空2。
tblPagesID ⾃动编号Sort integer 关键字Name text(255)HREF text(255)3.default.htm<html><head><title>javascript Tree Control Template</title></head><frameset cols=""210,*""><frame src=""tree.asp"" name=""TOC""><frame src=""main.htm"" name=""basefrm""></frameset></html>4.main.htm<head><title></title></head><body><h2>Start Page</h2></body></html>5.tree.aspSet conn = Server.CreateObject(""ADODB.Connection"")Set Rs = Server.CreateObject(""ADODB.Recordset"")conn.open ""DRIVER=Microsoft Access Driver (*.mdb);DBQ="" & Server.MapPath(""toc.mdb"")strsql = ""SELECT tblCategory.Root, tblCategory.[ID], tblCategory.Sort AS CatSort, tblPages.sort AS LinkSort, tblCategory. [Name] AS CatName, tblCategory.HREF AS CatURL, tblPages.[Name] AS LinkName, tblPages.href AS LinkURL FROM tblCategory LEFT JOIN tblPages ON tblCategory.[ID] = tblPages.[ID] ORDER BY tblCategory.root ASC, tblCategory.Sort, tblPages.sort""rs.open strsql, conn, 2, 2if not rs.eof then rs.movefirstcurrentID = """" %><html><head><link rel=""stylesheet"" href=""ftie4style.css""><!-- Infrastructure code for the tree --><script src=""ftiens4.js""></script><!-- Execution of the code that actually builds the specific tree --><script>USETEXTLINKS = 1<%Do While Not Rs.EOFIf Rs(""Root"") = True Then %>foldersTree = gFld(""<%= Rs(""CatName"") %>"", ""<%= Rs(""CatURL"") %>"")<% Else %>aux1 = insFld(foldersTree, gFld(""<%= Rs(""CatName"") %>"", ""<%= Rs(""CatURL"") %>"")) <% currentID = Rs(""ID"")savedID = Rs(""ID"")Do While currentID = savedID and not rs.eofif Rs(""LinkName"") <> """" Then %>insDoc(aux1, gLnk(0, ""<%= Rs(""LinkName"") %>"", ""<%= Rs(""LinkURL"") %>""))<%end ifRs.MoveNextif not rs.eof then currentID = Rs(""ID"")LoopEnd Ifif currentID = """" then rs.movenextLoop %></script><script>initializeDocument()</script><base target=""basefrm""><title></title></head><body bgcolor=""white""></body></html>。
简单但完整的树形列表+多选(复选)框实现⽅式多级分类通常做成树形的,如果分类是单选的,只要递归返回树形结构,⽤下拉列表显⽰就ok了。
当分类要求多选的时候,我们需要给每个分类都加上复选框。
在⾥TreeView可以显⽽易见的做到这个,然⽽TreeView服务端控件不但⽣成⽐较ugly的html代码,⽽且所需写代码的时候其实也并不是最少。
下⾯给出我的⼀个简单(代码数较少)但是完整的实现⽅式,除了显⽰,还包括取得选中值以及对树形列表赋值。
需要达到的效果如下,点击⼀个span可展开或收起树形列表。
我选择⽤ul显⽰树形列表,这也是⼀个常⽤的⽅式。
下⾯是aspx页⾯的代码,⽤jquery编写相关的脚本。
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="/1999/xhtml"><head runat="server"><title></title><style type="text/css">body { font-size: 12px; font-family: Verdana, 微软雅⿊; }ul { margin: 0px 10px; padding: 0px 10px; list-style: none; }li { line-height: 16px; }</style><script src="Scripts/jquery.js" type="text/javascript"></script><script type="text/javascript">//选中itemList⾥的保存Id的Checkboxfunction checkItems(nodeName, itemList) {var arr = itemList.split(',');$.each(arr, function (i, n) {$("#" + nodeName + "-" + arr[i]).attr("checked", "checked");});}$(function () {//点击展开或收起树形列表$("#spCategory").click(function (event) {event.stopPropagation();var offset = $(this).offset();$('#ulCategory').css({ left: offset.left, top: offset.top + 30 }).toggle();});//取消弹出层本⾝冒泡事件$("#ulCategory").click(function (event) { event.stopPropagation(); });//点击页⾯其他位置使弹出层消失$(document).click(function () { $("#ulCategory").hide(); });});</script></head><body><span id="spCategory" style="border: solid 1px silver; line-height: 25px; padding: 3px 5px; cursor: pointer; float: left;">点击这⾥展开或收起分类</span><ul id="ulCategory" style="position: absolute; background-color: ActiveCaption; display: none;"><asp:Literal ID="ltrCategory" runat="server"></asp:Literal></ul></body></html>后台cs代码如下,主要是返回树形结构。
C#⽣成下拉列表树效果图:代码:[csharp]using System.Data;using System.Web.UI.WebControls;/// <summary>/// 根据DataTable⽣成下拉列表树/// </summary>public class DropDownListHelp{private string gridline;private DataTable dt;public DropDownListHelp(){////TODO: 在此处添加构造函数逻辑//}/// <summary>/// 根据Datatable⽣成树形下拉菜单/// </summary>/// <param name="datatable"></param>/// <param name="parentKeyField">上级节点关键字段</param>/// <param name="parentKey">上级节点值</param>/// <param name="keyField">本节点关键字段</param>/// <param name="sortString">排序字符串</param>/// <param name="ddl">DownList</param>public void createDropDownTree(DataTable datatable, string parentKeyField, string parentKey, string keyField, string textField, string sortString, DropDownList ddl){dt = datatable;ddl.Items.Add(new ListItem("", ""));addChildItems(parentKeyField, parentKey, keyField, textField, sortString, ddl);}/// <summary>/// 递归⽣成树节点/// </summary>/// <param name="parentKeyField">上级节点关键字段</param>/// <param name="parentKey">上级节点值</param>/// <param name="keyField">本节点关键字段</param>/// <param name="sortString">排序字符串</param>/// <param name="ddl">DownList控件</param>/// <returns></returns>private void addChildItems(string parentKeyField, string parentKey, string keyField, string textField, string sortString, DropDownList ddl) {DataView dv = new DataView(dt, parentKeyField + "='" + parentKey + "'", sortString, DataViewRowState.CurrentRows);int a = dv.Count;if (dv.Count == 0){return;}for (int i = 0; i < a; i++){gridline = "";dv.RowFilter = parentKeyField + "='" + parentKey + "'";dv.Sort = sortString;getTreeLine(parentKeyField, dv[i][parentKeyField].ToString(), keyField, dv[i][keyField].ToString(), sortString);dv.RowFilter = parentKeyField + "='" + parentKey + "'";dv.Sort = sortString;ddl.Items.Add(new ListItem(gridline + (i == a - 1 ? "┗" : "┣") + dv[i][textField].ToString(), dv[i][keyField].ToString()));addChildItems(parentKeyField, dv[i][keyField].ToString(), keyField, textField, sortString, ddl);}dv.Dispose();}/// <summary>/// 回溯⽣成树的连接线/// </summary>/// <param name="parentKeyField">上级节点关键字段</param>/// <param name="parentKey">上级节点值</param>/// <param name="keyField">本节点关键字段</param>/// <param name="nodeKey">本节点值</param>/// <param name="sortString">排序字符串</param>/// <returns></returns>private void getTreeLine(string parentKeyField, string parentKey, string keyField, string nodeKey, string sortString) {//选择⽗层节点DataView dv = new DataView(dt, keyField + "='" + parentKey + "'", sortString, DataViewRowState.CurrentRows); if (dv.Count > 0){//选择⽗节点同级节点dv.RowFilter = parentKeyField + "='" + dv[0][parentKeyField].ToString() + "'";dv.Sort = sortString;for (int j = 0; j < dv.Count; j++){if (dv[j][keyField].ToString() == parentKey){if (j == dv.Count - 1){gridline = " " + gridline;}else{gridline = "┃" + gridline;}}}getTreeLine(parentKeyField, dv[0][parentKeyField].ToString(), keyField, dv[0][keyField].ToString(), sortString); }dv.Dispose();}}调⽤:[csharp]DropDownListHelp ddlHelper = new DropDownListHelp();ddlHelper.createDropDownTree(dt, "parentID", "1", "ID","Text", "Text asc", DropDownList1);。
树形递归算法using System;using System.Collections;using System.Configuration;using System.Data;using System.Linq;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.Xml.Linq;using System.Data.SqlClient;namespace WebApp{public partial class LoadMenu : System.Web.UI.Page{DataSet ds = null;protected void Page_Load(object sender, EventArgs e){if (!IsPostBack){//this.InitPage();ds = GetDB("select * from page");TreeNode pTreeNpd = null;GetTreeNode("0",pTreeNpd);}}private void InitPage(){TreeNode treeNode = this.GetTreeNode();this.TreeViewMenu.Nodes.Add(treeNode);}private TreeNode GetTreeNode(){TreeNode treeNode = new TreeNode("菜单导航");DataSet ds = this.GetDB("select * from page where Parent = '0'");foreach (DataRow masterRow in ds.Tables[0].Rows){TreeNode masterNode = new TreeNode((string)masterRow["Text"]);masterNode.NavigateUrl = (string)masterRow["Page"];treeNode.ChildNodes.Add(masterNode);DataSet ds11 = this.GetDB("select * from page where Parent = '" + masterRow["RID"] + "'"); foreach (DataRow item in ds11.Tables[0].Rows){TreeNode masterNode1 = new TreeNode((string)item["Text"]);masterNode1.NavigateUrl = (string)item["Page"];masterNode.ChildNodes.Add(masterNode1);}}return treeNode;}private TreeNode GetTreeNode(string Parent, TreeNode treeNode){DataView dv = ds.Tables[0].DefaultView;dv.RowFilter = " [Parent]='" + Parent + "'";foreach (DataRowView item in dv){TreeNode tttrr = new TreeNode();if (treeNode == null){tttrr.Text = item["Text"].ToString();TreeViewMenu.Nodes.Add(tttrr);GetTreeNode(item["rid"].ToString(), tttrr);}else{tttrr.Text = item["Text"].ToString();tttrr.NavigateUrl = (string)item["Page"];treeNode.ChildNodes.Add(tttrr);}}return null;}private DataSet GetDB(string sql){SqlConnection con = new SqlConnection();con.ConnectionString = “";if(con.State == ConnectionState.Closed){con.Open();}SqlDataAdapter da = new SqlDataAdapter(sql, con); DataSet ds = new DataSet();da.Fill(ds);return ds;}}}。
下面是程序的启动页面tree.htm:
< html >
< script src="renderer.js" language="javascript" >< /script >
< head >< /head >
< body id=bodytree name="bodytree" onload="gettree();" >
< iframe id=getdata style="display:none" >< /iframe >
< /body >
< /html >
该页面装载时将执行renderer.js中的gettree函数。
html代码中的iframe部分实现了客户端和服务器端的通讯机制。
javascript函数gettree的代码如下:
function gettree() {
if (event.type == 'load') {
if (typeof(divtree0)!='object')
getdata.window.location.href = 'gettreedata.asp?level=0';
} else {
try {
objmanip = eval('divtree'+ event.srcelement.getattribute('elementid'));
if (objmanip.style.display == 'none') {
objmanip.style.display = '';
} else {
objmanip.style.display = 'none';
}
} catch (e) {
getdata.window.location.href = 'gettreedata.asp?level='+ event.srcelement.getattribute('elementid');
}
event.cancelbubble = true;
}
}
当文档装载时,onload事件被触发,gettree函数得以执行。
函数检查容器divtree0是否存在,并为iframe(id为
getdata)读取第一层节点(这些节点的父节点id为0)。
如前所述,所有的节点都必须处理鼠标单击事件,而且事件句柄都是
gettree函数。
当某个节点(如div1)接收到一个鼠标事件时,程序将执行gettree函数中的else部分。
如果发送该事件的节点已
经读取了子节点,则程序检查这些子节点是否已经显示,然后切换子节点的显示状态,从而实现了该层节点的扩展或折叠效果。
检
查子节点是否显示的if语句封装在一个try块内,因此当子节点不存在时,程序将执行catch部分,调用服务器脚本
gettreedata.asp读取子节点内容。
最后,程序设置event.cancelbubble = true,目的是禁止上一层容器处
理该事件。
服务器脚本gettreedata.asp返回的html代码类如:
< html >
< body onload="parent.populatetree('1|0|节点1|2|0|节点2|3|0|节点3|4|0|节点4|');" >
< /body >
< /html >
可以看到,这里的onload事件又调用了另外一个javascript函数populatetree。
populatetree函数代码如下:
function populatetree(strdata) {
var arrsplitdata;
var icnt;
var objtempdiv;
var objmaindiv;
if (strdata=='') return;
arrsplitdata = strdata.split("|");
objmaindiv = document.createelement('div');
objmaindiv.id = 'divtree'+ arrsplitdata[1];
objmaindiv.style.csstext = 'position:relative;left:10px;cursor:hand;';
for (icnt=0;icnt< arrsplitdata.length-1;icnt+=3) {
objtempdiv = document.createelement('< div onclick='gettree()'onselectstart='return false;'> ');
objtempdiv.id = 'div'+ arrsplitdata[icnt];
objtempdiv.innerhtml = arrsplitdata[icnt+2];
objtempdiv.setattribute('elementid',arrsplitdata[icnt]);
objtempdiv.setattribute('parentelementid',arrsplitdata[icnt+1]);
objtempdiv.style.csstext = 'position:relative;cursor:hand;color:red;width:100px;font-size:x-small; ';
objmaindiv.appendchild(objtempdiv);
}
if (arrsplitdata[1]=='0')
document.body.appendchild(objmaindiv);
else
eval('div'+ arrsplitdata[1]).appendchild(objmaindiv);
}
我们已经知道,populatetree函数由onload事件调用,它的参数是一个字符串,比如上例中的“1|0|节点1|2|0|节点
2|3|0|节点3|4|0|节点4|”,它是一个“节点标识|父节点标识|节点文本|……”的列表。
如果某个节点不含子节点,则该参数是一个空字符串,此时populatetree直接返回。
如果子节点存在,
则可以利用split函
数将子节点列表以数组形式保存。
再接下来,就可以创建该层节点的容器,比如divtree0,然后遍历数组创建各个节点,如
div1,div2……。
如果某个节点的父节点id为0,说明该节点没有父节点,程序将把容器divtree0加入文档的body;否则当该节点
的父节点id不为0,则创建与其父节点对应的容器“divtree< < 父节点id > >”。
在创建节点的同时指定了鼠标单击事件的句柄
gettree函数。
注:可以修改gettreedata.asp,使其返回的子节点列表(即populatetree的参数)形式为“节点id|节点文本|……”,也
就是省略父节点id,因为任何一组子节点列表其父节点总是相同的。
同时,还必须修改populatetree函数,使其接受两个参数,第
一个参数是子节点列表,第二个是父节点id。
当节点数量较多时,采用这种方法有利于减少数据传输量,提高效率。
四、其他说明
综上所述,整个程序的工作过程可以描述为:
浏览器读入文档,执行gettree函数。
gettree调用gettreedata.asp,读取第一层节点数据,然后回调populatetree函数。
populatetree函数生成divtree0以及节点div1,div2,……。
用户单击任意一个节点。
gettree函数检查“divtree< < 节点id > >” 是否已经存在,如存在则切换子节点显示状态,否则读取子节点列表。
gettreedata.asp返回子节点列表,回调populatetree函数。
populatetree生成相应的容器“divtree< < 父节点id > >”,并生成节点“div< < 节点id1 > >”,“div< < 节点id2 >
>”……。
重复步骤4。
运行示例程序步骤如下(默认目录d:inetpubwwwroot):
创建一个目录,把所有文件拷贝到该目录。
在web服务器上发布该目录。
修改tree.dsn中的数据库路径。
修改gettreedata.asp中tree.dsn文件路径。
用浏览器打开tree.htm。
示例程序中的iframe是隐藏的,如果要显示它,则请删除iframe的属性“style="display:none"”,此时还可以查看节点
的html源代码。