首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET TreeView 數據庫遞歸綁定完整實現:從數據表到樹狀結構

     編輯:ASP.NET 基礎

前言

TreeView 是展示分類目錄、組織架構、菜單權限等層級數據的經典控件。本文提供基於遞歸算法的完整綁定方案,涵蓋數據庫表設計、後台遞歸構建樹節點、前端聲明式綁定,代碼結構清晰、易於擴展。

數據庫表設計

CREATE TABLE TreeViewName (
    MenuID INT PRIMARY KEY IDENTITY(1,1),
    MenuName NVARCHAR(100) NOT NULL,
    ParentID INT DEFAULT 0,  -- 0 表示根節點
    SortIndex INT DEFAULT 0  -- 同級排序
);

示例數據

MenuIDMenuNameParentIDSortIndex
1系統管理01
2用戶管理11
3角色管理12
4日志查詢13
5業務模塊02
6訂單管理51

前端頁面

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TreeViewDemo._Default" %>
<html xmlns="https://www.w3.org/1999/xhtml">
<body>
    <form id="form1" runat="server">
        <div>
            <asp:TreeView ID="TreeView1" runat="server" ShowLines="True" 
                ExpandDepth="0" > <!-- 默認折疊 -->
            </asp:TreeView>
        </div>
    </form>
</body>
</html>

後台核心邏輯

1. 一次性讀取全量數據到 DataTable

private DataTable _dtSource;

private DataTable LoadTreeData()
{
    string connStr = ConfigurationManager.ConnectionStrings["sql"].ConnectionString;
    using (var conn = new SqlConnection(connStr))
    using (var cmd = new SqlCommand("SELECT * FROM TreeViewName ORDER BY SortIndex", conn))
    using (var adapter = new SqlDataAdapter(cmd))
    {
        var dt = new DataTable();
        adapter.Fill(dt);
        return dt;
    }
}

2. 遞歸構建樹節點

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        _dtSource = LoadTreeData();
        BuildTree();
    }
}

private void BuildTree()
{
    // 1. 獲取根節點
    DataRow[] roots = _dtSource.Select("ParentID = 0");
    
    if (roots.Length == 0)
    {
        TreeView1.Nodes.Add(new TreeNode("無數據", "empty"));
        return;
    }

    foreach (DataRow row in roots)
    {
        TreeNode node = CreateNode(row);
        TreeView1.Nodes.Add(node);
        BuildChildNodes(node);
    }
}

private TreeNode CreateNode(DataRow row)
{
    return new TreeNode
    {
        Text = row["MenuName"].ToString(),
        Value = row["MenuID"].ToString(),
        ToolTip = row["MenuID"].ToString(), // 攜帶 ID 便於後續處理
        Expanded = false,
        SelectAction = TreeNodeSelectAction.Expand // 點擊展開而非選中
    };
}

private void BuildChildNodes(TreeNode parentNode)
{
    string parentId = parentNode.Value;
    DataRow[] children = _dtSource.Select($"ParentID = {parentId}");

    foreach (DataRow row in children)
    {
        TreeNode child = CreateNode(row);
        parentNode.ChildNodes.Add(child);
        BuildChildNodes(child); // 遞歸處理下一層
    }
}

進階優化與擴展

1. 支援海量數據的分頁/懶加載

// TreeView 節點展開事件:按需加載子節點
protected void TreeView1_TreeNodePopulate(object sender, TreeNodeEventArgs e)
{
    if (e.Node.ChildNodes.Count == 1 && e.Node.ChildNodes[0].Value == "loading")
    {
        e.Node.ChildNodes.Clear(); // 移除佔位節點
        LoadChildrenOnDemand(e.Node); // 從數據庫查詢並添加真實子節點
        e.Node.PopulateOnDemand = false; // 標記已加載
    }
}

// 前端需設置 PopulateOnDemand="true" 並添加佔位節點
private void CreateNodeWithLazy(DataRow row, TreeNode parent)
{
    var node = CreateNode(row);
    if (HasChildren(row["MenuID"]))
    {
        node.PopulateOnDemand = true;
        node.ChildNodes.Add(new TreeNode("加載中...", "loading"));
    }
    parent.ChildNodes.Add(node);
}

2. 節點樣式與圖標自定義


    
    
    
    

3. 選中節點事件處理

protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
{
    string menuId = TreeView1.SelectedNode.Value;
    string menuName = TreeView1.SelectedNode.Text;
    // 根據菜單 ID 加載對應內容頁面
    Response.Redirect($"Content.aspx?menuId={menuId}");
}

性能對比:遞歸 vs 迭代 vs 懶加載

方案適用數據量首屏速度內存佔用實現複雜度
全量遞歸(本文)< 2000 節點快中低
迭代構建< 5000 節點快中中
懶加載無上限極快低高

常見問題排查

  • 樹不顯示:檢查連接字符串、表名、字段名大小寫;確認 _dtSource 有數據
  • 死循環/棧溢出:數據中存在循環引用(A→B→A),需在遞歸入口加入已訪問 ID 集合檢測
  • 層級過深顯示異常:CSS 控制縮進寬度,或設置 TreeView 的 MaxDepth 限制
  • Postback 後樹狀態丟失:TreeView 自動維護 ViewState,確保 EnableViewState="true"

結語

本文提供的遞歸綁定方案代碼簡潔、邏輯清晰,適合中小型層級數據展示。對於大數據量、高併發場景,建議演進至懶加載模式或引入前端虛擬滾動樹組件(如 zTree、Vue Tree)配合 WebAPI 分頁接口,實現極致體驗與性能平衡。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved