存储过程+数据缓存版的TreeView控件“无限”分级实现
在这里有两点值得注意的,一就是表设计的时候parentId字段保存的是其父类ID(上一级结点)值;二是C#程序里面递归调用创建子结点的方法。为了把注意力集中到有关TreeView分级的代码实现上,对于数据库的查询取数据等相关操作我写成了SQLHelp类并放在App_Code文件夹中,该类仅写出了本实例需要用到的功能,很简单。以下分别为default.aspx(页面上仅放置了一个名为ProductTreeView的 TreeView控件)、default.aspx.cs的代码文件(包括CreateTreeView()、CreateChildNode()两个主要的方法)。
default.aspx文件: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.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>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> <asp:TreeView ID="ProductTreeView" runat="server" ExpandDepth="1"> </asp:TreeView> </div> </form> </body> </html> default.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; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { CreateTreeView(); } } private void CreateTreeView() { ///从数据库获取数据 SQLHelp sp = new SQLHelp(); DataTable DT = sp.myDataTable("TVProductsCatalog"); sp.myClose(); ///创建根结点 TreeNode root = new TreeNode(); root.Text = "产品目录[根]"; root.Value = "0"; root.NavigateUrl = ""; ProductTreeView.Nodes.Add(root); ///创建子结点 CreateChildNode(root,DT); } private void CreateChildNode(TreeNode parentNode, DataTable dt) { ///选择子结点 DataRow[] rowList = dt.Select("parentId=" + parentNode.Value); ///创建子结点 foreach (DataRow row in rowList) { TreeNode node = new TreeNode(); node.Text = row["cName"].ToString(); node.Value = row["CID"].ToString(); node.NavigateUrl = "product-list.aspx?CurrentSort="+node.Value+""; parentNode.ChildNodes.Add(node); ///递归调用 CreateChildNode(node,dt); } } } 数据库操作类SQLHelp.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; public class SQLHelp { //定义全局数据库连接变量 public SqlConnection myConnection; //在构造函数中打开数据库连接 public SQLHelp() { myConnection = new SqlConnection(connString()); myConnection.Open(); } /// <summary> /// 返回web.config中"<connectionStrings>"节的内容 /// </summary> /// <returns></returns> private string connString() { return System.Configuration.ConfigurationManager.ConnectionStrings["DataConnectionString"].ToString(); } /// <summary> /// 执行查询存储过程、缓存数据并返回数据表 /// </summary> /// <param name="spName"></param> /// <returns></returns> public DataTable myDataTable(string spName) { DataTable table = (DataTable)HttpContext.Current.Cache["CacheData"]; //从缓存取数据 if (table == null) { if (myConnection.State == ConnectionState.Closed) { myConnection.Open(); } SqlCommand cmd = new SqlCommand(spName, myConnection); cmd.CommandType = CommandType.StoredProcedure; cmd.ExecuteNonQuery(); SqlDataAdapter da = new SqlDataAdapter(cmd); table = new DataTable(); da.Fill(table); HttpContext.Current.Cache.Insert("CacheData", table); //将数据写入缓存 } return table; } /// <summary> /// 关闭连接并释放资源 /// </summary> public void myClose() { myConnection.Close(); myConnection.Dispose(); } } 一点说明: 1、TreeView控件有一个ExpandDepth属性,默认是“FullyExpand”即全部展开,可以根据自己的情况设置为1、2……我在此处只展开了一级分类,上图效果是便于演示手动展开的。 2、数据缓存在数据量不大的情况下性能提升的效果可能并不明显,这里权且当作缓存知识的练习吧。 3、本文标题中无限二字加了引号,因为据说C#的递归是有层数限制的,最多300层,我没有实证过。 4、如果在站点中其它页面也要使用到该分类,那么可以考虑做成用户控件,这样只需一两行代码就可以引用它了。 5、要实现TreeView更复杂的功能及更好的呈现等,好象就需要重写TreeView,控件开发目前还不怎么熟悉,学习中。 全文完了,谢谢您浏览,敬请指教。 原帖:http://www.cnblogs.com/ataman1/archive/2008/09/05/1285182.html |