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

ASP.NET GridView 多層巢狀結構與摺疊展開功能實作

     編輯:ASP.NET 基礎

功能展示

實現三層巢狀 GridView:年份 → 月份 → 影片檔案。每層提供摺疊/展開圖示,點擊切換子層顯示狀態。整體封裝於用戶控件 InsusMenu.ascx 供多頁重用。

前端標記 InsusMenu.ascx

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="InsusMenu.ascx.vb" Inherits="AscxControls_InsusMenu" %>

<!-- 摺疊/展開 JavaScript -->
<script type="text/javascript">
    function ShowHidde(sid, evt) {
        evt = evt || window.event;
        var target = evt.target || evt.srcElement;
        var objDiv = document.getElementById("div" + sid);
        objDiv.style.display = (objDiv.style.display == "none") ? "block" : "none";
        target.title = (objDiv.style.display == "none") ? "展開" : "摺疊";
        var imgId = 'img' + sid;
        document.getElementById(imgId).src = (objDiv.style.display == "none") ? "Image/+.gif" : "Image/-.gif";
    }
</script>

<!-- 第一層:年份 -->
<asp:GridView ID="GridViewYear" runat="server" Width="100%" AutoGenerateColumns="False" 
    OnRowDataBound="GridViewYear_RowDataBound" ShowHeader="false" BorderWidth="0">
    <Columns>
        <asp:TemplateField>
            <ItemStyle BorderWidth="0" Height="25" />
            <ItemTemplate>
                <img id='img<%# Eval("Year")%>' style="border:0;" src="Image/+.gif" 
                    onclick="ShowHidde('<%# Eval("Year")%>', event)" />
                <%# Eval("Year") & "年" %>
                <div id='div<%# Eval("Year")%>' style="display: none;">

                    <!-- 第二層:月份 -->
                    <asp:GridView ID="GridViewMonth" runat="server" OnRowDataBound="GridViewMonth_RowDataBound" 
                        Width="100%" AutoGenerateColumns="False" ShowHeader="False" BorderWidth="0">
                        <Columns>
                            <asp:TemplateField>
                                <ItemStyle BorderWidth="0" Height="25" />
                                <ItemTemplate>
                                    <img id='img<%# Eval("Month")%>' style="border:0; padding-left:20px;" src="Image/+.gif" 
                                        onclick="ShowHidde('<%# Eval("Month")%>', event)" />
                                    <%# Eval("Month") & "月" %>
                                    <div id='div<%# Eval("Month")%>' style="display: none;">

                                        <!-- 第三層:影片檔案 -->
                                        <asp:GridView ID="GridViewVideoFile" runat="server" Width="100%" 
                                            AutoGenerateColumns="False" ShowHeader="False" BorderWidth="0">
                                            <Columns>
                                                <asp:TemplateField>
                                                    <ItemStyle BorderWidth="0" Height="25" />
                                                    <ItemTemplate>
                                                        <img style="border:0; padding-left:40px; padding-right:5px; width:16px; height:16px; vertical-align:middle;" 
                                                            src="Image/m_file.png" />
                                                        <asp:HyperLink ID="HyperLinkPlayer" runat="server" 
                                                            NavigateUrl='<%# "~/VideoPlayer.aspx?videokey=" & Eval("VideoLibrary_nbr")%>' 
                                                            Text='<%# Eval("OldFileName").Substring(0, Eval("OldFileName").LastIndexOf("."))%>' 
                                                            Target="_blank"></asp:HyperLink>
                                                    </ItemTemplate>
                                                </asp:TemplateField>
                                            </Columns>
                                        </asp:GridView>

                                    </div>
                                </ItemTemplate>
                            </asp:TemplateField>
                        </Columns>
                    </asp:GridView>

                </div>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

後端代碼 InsusMenu.ascx.vb

Imports System.Data
Imports Insus.NET

Partial Class AscxControls_InsusMenu
    Inherits System.Web.UI.UserControl

    Dim objVideoLibrary As New VideoLibrary()

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
        If Not IsPostBack Then Data_Binding()
    End Sub

    Private Sub Data_Binding()
        ' 繫結第一層:年份
        Me.GridViewYear.DataSource = objVideoLibrary.GetYear()
        Me.GridViewYear.DataBind()
    End Sub

    ' 繫結第二層:月份
    Protected Sub GridViewYear_RowDataBound(sender As Object, e As GridViewRowEventArgs)
        Dim dvr As DataRowView = DirectCast(e.Row.DataItem, DataRowView)
        If e.Row.RowType = DataControlRowType.DataRow Then
            Dim gvMonth As GridView = DirectCast(e.Row.FindControl("GridViewMonth"), GridView)
            If gvMonth IsNot Nothing Then
                objVideoLibrary.Year = ConvertData.ToSmallInt(dvr("Year"))
                gvMonth.DataSource = objVideoLibrary.GetMonthByYear()
                gvMonth.DataBind()
            End If
        End If
    End Sub

    ' 繫結第三層:影片檔案
    Protected Sub GridViewMonth_RowDataBound(sender As Object, e As GridViewRowEventArgs)
        Dim dvr As DataRowView = DirectCast(e.Row.DataItem, DataRowView)
        If e.Row.RowType = DataControlRowType.DataRow Then
            Dim gvVideo As GridView = DirectCast(e.Row.FindControl("GridViewVideoFile"), GridView)
            If gvVideo IsNot Nothing Then
                objVideoLibrary.Year = ConvertData.ToSmallInt(dvr("Year"))
                objVideoLibrary.Month = ConvertData.ToTinyInt(dvr("Month"))
                gvVideo.DataSource = objVideoLibrary.GetByYearAndMonth()
                gvVideo.DataBind()
            End If
        End If
    End Sub
End Class

關鍵技術點

  1. 唯一 ID 產生:使用資料欄位(Year、Month)作為 HTML 元素 ID 的一部分(id='img<%# Eval("Year")%>'),確保每個摺疊區塊 ID 唯一。
  2. JavaScript 切換邏輯:透過 style.display 切換 div 顯示/隱藏,同步更新圖示 src 與 title。
  3. RowDataBound 遞迴繫結:父層 RowDataBound 中 FindControl 取得子 GridView,依父層資料鍵值查詢並繫結子層資料。
  4. 用戶控件封裝:將多層巢狀邏輯封裝於 .ascx,多頁引用時只需 <uc:InsusMenu runat="server" />。

優化建議

  • 資料一次載入:目前每層展開時才查詢資料(PostBack),若資料量不大,可考慮一次查詢完整樹狀結構,前端純 JS 控制顯示/隱藏,減少伺服器往返。
  • UpdatePanel 局部更新:包裹於 UpdatePanel 中可避免整頁閃爍。
  • 現代化替代:新專案建議使用前端框架(Vue/React)配合 Tree 組件,資料以 JSON 遞迴結構一次載入,體驗更流暢。

總結

本文展示 ASP.NET Web Forms 利用巢狀 GridView + JavaScript 實現多層摺疊展開選單,代碼結構清晰,封裝為用戶控件便於重用。適合傳統 Web Forms 專案快速構建樹狀導航。

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