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

ASP.NET GridView 分頁功能完整實作與進階技巧

     編輯:關於ASP.NET

GridView 內建分頁功能只需設定幾個屬性並處理 PageIndexChanging 事件即可啟用。但實務上常遇到:自訂分頁 UI、大量資料效能、分頁狀態保持、AJAX 部分更新等需求。

基礎啟用步驟

  1. AllowPaging="true"
  2. PageSize="10" (預設 10)
  3. PagerSettings-Mode="NumericFirstLast" (或 NextPrevious、Numeric)
  4. 加入事件:OnPageIndexChanging="GridView1_PageIndexChanging"
  5. 事件處理:
    protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        GridView1.PageIndex = e.NewPageIndex;
        BindGridView(); // 重新綁定資料
    }
    

完整範例


<asp:GridView ID="GridView1" runat="server" 
    AllowPaging="true" PageSize="15"
    AutoGenerateColumns="false"
    OnPageIndexChanging="GridView1_PageIndexChanging"
    OnSorting="GridView1_Sorting"
    PagerSettings-Mode="NumericFirstLast"
    PagerSettings-PageButtonCount="10"
    PagerStyle-CssClass="grid-pager"
    CssClass="table table-striped">
    <Columns>
        <asp:BoundField DataField="Id" HeaderText="編號" SortExpression="Id" />
        <asp:BoundField DataField="Name" HeaderText="名稱" SortExpression="Name" />
        <asp:BoundField DataField="CreateTime" HeaderText="建立時間" DataFormatString="{0:yyyy/MM/dd HH:mm}" />
    </Columns>
</asp:GridView>

private void BindGridView()
{
    // 範例:從資料庫撈資料
    string sql = "SELECT Id, Name, CreateTime FROM Products WHERE IsActive=1";
    using (var conn = new SqlConnection(ConnStr))
    using (var da = new SqlDataAdapter(sql, conn))
    {
        var dt = new DataTable();
        da.Fill(dt);
        
        // 若有排序狀態,套用排序
        if (ViewState["SortExpr"] != null)
        {
            dt.DefaultView.Sort = ViewState["SortExpr"] + " " + ViewState["SortDir"];
        }
        
        GridView1.DataSource = dt;
        GridView1.DataBind();
    }
}

protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    GridView1.PageIndex = e.NewPageIndex;
    BindGridView();
}

進階技巧 1:自訂分頁樣式


<PagerTemplate>
    <asp:LinkButton runat="server" CommandName="Page" CommandArgument="First" Text="<< 首頁" />
    <asp:LinkButton runat="server" CommandName="Page" CommandArgument="Prev" Text="< 上頁" />
    <span class="page-info">第 <%# Container.PageIndex + 1 %> 頁 / 共 <%# Container.PageCount %> 頁</span>
    <asp:LinkButton runat="server" CommandName="Page" CommandArgument="Next" Text="下頁 >" />
    <asp:LinkButton runat="server" CommandName="Page" CommandArgument="Last" Text="尾頁 >>" />
    <asp:TextBox ID="txtGoPage" runat="server" Width="40" CssClass="page-input" />
    <asp:LinkButton runat="server" CommandName="Page" CommandArgument='<%# ((TextBox)Container.FindControl("txtGoPage")).Text %>' Text="跳轉" />
</PagerTemplate>

搭配 CSS 美化,打造類似現代前端分頁元件的體驗。

進階技巧 2:大量資料效能優化 (資料庫端分頁)

預設 DataTable 全撈再分頁,資料量大時記憶體與速度皆不可接受。改用 SQL Server OFFSET/FETCH (2012+) 或 ROW_NUMBER() (2005+)。


private DataTable GetPagedData(int pageIndex, int pageSize, out int totalCount)
{
    string sql = @"
        SELECT COUNT(*) FROM Products WHERE IsActive=1;
        SELECT Id, Name, CreateTime 
        FROM Products 
        WHERE IsActive=1
        ORDER BY CreateTime DESC
        OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY;";

    using (var conn = new SqlConnection(ConnStr))
    using (var cmd = new SqlCommand(sql, conn))
    {
        cmd.Parameters.AddWithValue("@Offset", pageIndex * pageSize);
        cmd.Parameters.AddWithValue("@PageSize", pageSize);
        conn.Open();
        using (var reader = cmd.ExecuteReader())
        {
            totalCount = reader.Read() ? reader.GetInt32(0) : 0;
            reader.NextResult();
            var dt = new DataTable();
            dt.Load(reader);
            return dt;
        }
    }
}

protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    int total;
    GridView1.DataSource = GetPagedData(e.NewPageIndex, GridView1.PageSize, out total);
    GridView1.VirtualItemCount = total; // 啟用自訂分頁計數
    GridView1.PageIndex = e.NewPageIndex;
    GridView1.DataBind();
}

需設定 GridView.AllowCustomPaging="true" 並指定 VirtualItemCount。

進階技巧 3:UpdatePanel 非同步分頁


<asp:UpdatePanel ID="upGrid" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:GridView ... />
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="GridView1" EventName="PageIndexChanging" />
    </Triggers>
</asp:UpdatePanel>

避免整頁重新整理,提升使用者體驗。

進階技巧 4:分頁狀態持久化 (跨頁面返回保持頁碼)


// 儲存於 Session,Key 含頁面識別
string pageKey = "GridView1_PageIndex_" + Request.Path;
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    GridView1.PageIndex = e.NewPageIndex;
    Session[pageKey] = e.NewPageIndex;
    BindGridView();
}

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack && Session[pageKey] != null)
    {
        GridView1.PageIndex = (int)Session[pageKey];
    }
}

常見問題排查

問題原因解決
分頁按鈕不顯示資料筆數 ≤ PageSize正常行為;或設 PagerSettings-Visible="true" 強制顯示
點擊分頁無反應缺少 OnPageIndexChanging 或未重新綁定檢查事件綁定與 BindGridView()
分頁後排序消失重新綁定未套用排序 ViewStateBindGridView() 中套用 dt.DefaultView.Sort
自訂分頁總筆數錯誤未設定 VirtualItemCount查詢 COUNT(*) 並指派

總結

GridView 分頁核心三步驟:開啟屬性 → 處理 PageIndexChanging → 重新綁定。實務上務必搭配**資料庫端分頁**、**排序狀態保持**、**非同步更新**三大增強,才能應對真實業務場景。

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