GridView 分頁元件

GridView 分頁的作法

2015-11-27 更新:內文作法非真分頁

前言:

平時我們使用GridView,需要使用分頁時,最簡單的方式如下:

<asp:gridview allowpaging="true" id="GridView1" onpageindexchanging="GridView1_PageIndexChanging" pagesize="4" runat="server">
</asp:gridview>
protected void Page_Load(object sender, EventArgs e)   
{   
    if (!this.Page.IsPostBack)   
    {   
          getData(); //取資料   
    }   
}   
  
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)   
{   
    GridView1.PageIndex = e.NewPageIndex;   
    getData(); //取資料   
}  

public void getData()
{
    DataSet ds = new DataSet();
    SqlDataAdapter sqlDA = new SqlDataAdapter(SqlCmd, sqlConn);
    sqlDA.Fill(ds, "Data");
    GridView1.DataSource = ds.Tables["Data"];
    GridView1.DataBind();
}

在 GridView中增加 OnPageIndexChanging 事件,就可以使用分頁功能。

畫面結果圖:

可以參考:

1. MSDN 論壇 該如何撰寫Gridview的分頁功能呢?

2. MIS2000 Lab大的文章 - 撰寫ADO.NET DataReader的分頁程式

如果使用者需要複雜的分頁需求時,(例如:第一頁、最末頁、跳頁、筆數統計等),此時上述介紹的陽春寫法就不符使用;所以如有這樣的需求,可以參考將要介紹的分頁元件,以下開始介紹:

畫面結果圖:

前置介紹與準備:

1. 筆者使用的是 AdventureWorks範例資料庫,大家可以參考小歐大的這篇文章 - 安裝 AdventureWorks 範例資料庫

2. 筆者將分頁所用到的控制項,建立為使用者控制項,大家須使用時,請事先將其拉入Aspx中。

ASP.NET前置介紹與準備:

web.config

<appSettings>
        <add key="ConnectString" value="Data Source=(local);DataBase=AdventureWorks;User ID=sa;Password=123456"/>
</appSettings>

.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UseUCPageDemo.aspx.cs" Inherits="Demo_PageUserControl.UseUCPageDemo" %>
<%@ Register src="UControls/PageControl.ascx" tagname="PageControl" tagprefix="uc1" %>

<!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>使用Pages使用者控制項_GridView分頁</title>
    <link href="<%=ResolveUrl("~/Css/Style.css") %>" type="text/css" rel="stylesheet" />
    <style type="text/css">
        .pageclass
        {
            display:none;    
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div style="width:600px; height:20px; font-size:12px; margin:10px 0 0 0;">
        <div style="float:left;">範例程式 - 資料庫:AdventureWorks / Product</div>
        <div style="float:right;">共 <asp:Label ID="lblTotal" runat="server" Font-Bold="true" ForeColor="Blue"></asp:Label> 筆</div>
    </div>
    <div style="width:600px; font-size:12px;">
        <asp:GridView ID="gvProduct" runat="server" CssClass="mGrid" AlternatingRowStyle-CssClass="alt"
            GridLines="None" AllowPaging="true" PagerStyle-CssClass="pgr"
            PageSize="20" onpageindexchanging="gvProduct_PageIndexChanging">
            <PagerStyle CssClass="pageclass" />
            <AlternatingRowStyle CssClass="alt"></AlternatingRowStyle>
        </asp:GridView>
        <div align="center">
            <uc1:PageControl ID="PageControl1" runat="server" />
        </div>
    </div>
    </form>
</body>
</html>

.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace Demo_PageUserControl
{
    public partial class UseUCPageDemo : System.Web.UI.Page
    {
        int intTotal;

        public int getDataSetTotal
        {
            get { return intTotal; }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.Page.IsPostBack)
            {
                getProductData();
                //設定(起始頁面, 是否載入資料)
                SetPageControl("First", true);
            }
            else
            {
                SetPageControl("", false);
            }
        }

        private void getProductData()
        {
            string SqlCmd = "SELECT ProductNumber, [Name], Color, SafetyStockLevel, ReorderPoint FROM Production.Product";
            this.gvProduct.DataSource = GetDataSet(SqlCmd).Tables[0];
            this.gvProduct.DataBind();
            //資料總筆數
            this.lblTotal.Text = getDataSetTotal.ToString();
        }

        //設定PageControl資料
        public void setPageData()
        {
            SqlConnection sqlConn = new SqlConnection(ConfigurationManager.AppSettings["ConnectString"]);
            string SqlCmd = "SELECT ProductNumber, [Name], Color, SafetyStockLevel, ReorderPoint FROM Production.Product";
            using (SqlDataAdapter Adapter = new SqlDataAdapter(SqlCmd, sqlConn))
            {
                DataSet dsPages = new DataSet();
                Adapter.Fill(dsPages, "Pages");
                //設定 PageControl 的 dsDataSet 屬性
                PageControl1.dsDataSet = dsPages; 
                //設定 PageControl 的 gvGridView 屬性
                PageControl1.gvGridView = this.gvProduct; 
                if (dsPages == null)
                {
                    //設定 PageControl 的 TotalRecCount 屬性
                    PageControl1.TotalRecCount = 0; 
                }
                else
                {
                    //設定 PageControl 的 TotalRecCount 屬性
                    PageControl1.TotalRecCount = dsPages.Tables[0].Rows.Count; 
                }
            }
        }

        ////<summary>
        ////設定PageControl
        ///</summary>
        ////<param name="PageKind" />分頁往返種類:First/Last/Prev/Next/空值 
        ////<param name="lDataBind" />True/False 
        public void SetPageControl(string PageKind, bool lDataBind) 
        { 
            setPageData(); 
            if (!string.IsNullOrEmpty(PageKind)) 
            { 
                PageControl1.SetPage(PageKind, lDataBind); 
            } 
        } 
		
        protected void gvProduct_PageIndexChanging(object sender, GridViewPageEventArgs e) 
        { 
            PageControl1.SetPage(Convert.ToString(e.NewPageIndex + 1), false); 
        } 
			
        ////<summary>
        ////取得資料表查詢結果 
        ////</summary>
        ////<param name="SQL" />SQL語法 
        ////<returns>回傳結果DataTable</returns> 
        public DataSet GetDataSet(string SQL) 
        { 
            using (SqlConnection sqlConn = new SqlConnection(ConfigurationManager.AppSettings[&quot;ConnectString&quot;])) 
            { 
                using (SqlDataAdapter adapter = new SqlDataAdapter(SQL, sqlConn)) 
                { 
                    DataSet ds = new DataSet(); 
                    adapter.Fill(ds); 
                    intTotal = ds.Tables[0].Rows.Count; 
                    return ds; 
                } 
            } 
        } 
    } 
}

使用者控制項 PageControl 說明:

.ascx

<%@ Control Language="C#" AutoEventWireup="false" CodeBehind="PageControl.ascx.cs" Inherits="Demo_PageUserControl.PageControl" %>
筆數:
<asp:Label ID="lblTotalCount" runat="server"></asp:Label>|
<asp:LinkButton ID="lnkFirstPage" runat="server" CommandName="First" CausesValidation="False" OnClick="lnkFirstPage_Click">第一頁</asp:LinkButton>|
<asp:LinkButton ID="lnkPrePage" runat="server" CommandName="Prev" CausesValidation="False" OnClick="lnkPrePage_Click">上一頁</asp:LinkButton>|
<asp:LinkButton ID="lnkNextPage" runat="server" CommandName="Next" CausesValidation="False" OnClick="lnkNextPage_Click">下一頁</asp:LinkButton>|
<asp:LinkButton ID="lnkLastPage" runat="server" CommandName="Last" CausesValidation="False" OnClick="lnkLastPage_Click">最末頁</asp:LinkButton>|頁數:
<asp:Label ID="lblCurrentPage" runat="server"></asp:Label>/<asp:Label ID="lblTotalPage" runat="server"></asp:Label>
<asp:DropDownList ID="ddlPages" runat="server" AutoPostBack="True" OnSelectedIndexChanged="ddlPages_SelectedIndexChanged">
</asp:DropDownList>
<asp:DropDownList ID="ddlPageSize" runat="server" AutoPostBack="True" OnSelectedIndexChanged="ddlPageSize_SelectedIndexChanged">
    <asp:ListItem Selected="True" Value="20">每頁 20 列</asp:ListItem>
    <asp:ListItem Value="30">每頁 30 列</asp:ListItem>
    <asp:ListItem Value="50">每頁 50 列</asp:ListItem>
    <asp:ListItem Value="100">每頁 100 列</asp:ListItem>
</asp:DropDownList>

.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;
using System.Collections.Generic;
using System.Diagnostics;

namespace Demo_PageUserControl
{
    public partial class PageControl : System.Web.UI.UserControl
    {
        #region " Web Form 設計工具產生的程式碼 "

        //此為 Web Form 設計工具所需的呼叫。
        [System.Diagnostics.DebuggerStepThrough()]

        private void InitializeComponent()
        {

        }

        //注意: 下列預留位置宣告是 Web Form 設計工具需要的項目。
        //請勿刪除或移動它。

        private void Page_Init(System.Object sender, System.EventArgs e)
        {
            //CODEGEN: 此為 Web Form 設計工具所需的方法呼叫
            //請勿使用程式碼編輯器進行修改。
            InitializeComponent();
        }

        #endregion

        private bool _lChange;
        public bool lChange
        {
            get { return _lChange; }
        }

        private GridView _GridView = new GridView();
        public GridView gvGridView
        {
            set { _GridView = (GridView)value; }
        }

        private DataSet _DataSet = new DataSet();
        public DataSet dsDataSet
        {
            set { _DataSet = (DataSet)value; }
        }

        public bool lShowPageSize
        {
            get
            {
                if (this.ViewState["lShowPageSize"] == null)
                {
                    this.ViewState["lShowPageSize"] = true;
                }
                return Convert.ToBoolean(this.ViewState["lShowPageSize"]);
            }
            set { this.ViewState["lShowPageSize"] = value; }
        }

        public int TotalRecCount
        {
            get { return Convert.ToInt32(lblTotalCount.Text); }
            set { lblTotalCount.Text = Convert.ToString(value); }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            //在這裡放置使用者程式碼以初始化網頁
            if (!IsPostBack)
            {
                ddlPageSize.Visible = lShowPageSize;
            }
        }

        protected void ddlPages_SelectedIndexChanged(object sender, EventArgs e)
        {
            _lChange = true;
            SetPage(ddlPages.SelectedValue, false);
        }


        ////<summary> 
        /// 取得資料表查詢結果 
        ////</summary>
        ///<param name="PageKind" />分頁指定 
        ///<param name="lDataBind" />是否載入資料 
        public void SetPage(string PageKind, bool lDataBind) 
        { 
            int nCurrentPage = 0; 
            int nTotalPage = 0; 
            int nPage = 0; 
            int i = 0;

            if (lDataBind) 
            { 
                _GridView.PageIndex = 0; 
                nCurrentPage = _GridView.PageIndex + 1; 
            } 
            else 
            { 
                nTotalPage = (_GridView.PageCount > 0 ? _GridView.PageCount : 1); 
                if (_GridView.PageIndex >= _GridView.PageCount) 
                    _GridView.PageIndex = 0; nCurrentPage = _GridView.PageIndex + 1; 
            } 
			
            switch (PageKind) 
            { 
                case "First": 
                    nPage = 1; 
                    break; 
                case "Last": 
                    nPage = nTotalPage; 
                    break; 
                case "Prev": 
                    nPage = nCurrentPage - 1; 
                    break; 
                case "Next": 
                    nPage = nCurrentPage + 1; 
                    break; 
                default: 
                    nPage = Convert.ToInt32(PageKind); 
                    break; 
            } 
			
            if (nPage < 1 | nPage > nTotalPage) 
            { 
                nPage = nCurrentPage;
            } 
			
            if (nPage != nCurrentPage | lDataBind) 
            { 
                _GridView.PageIndex = nPage - 1; 
                _GridView.Visible = true; 
				
                if ((_DataSet != null)) 
                { 
                    _GridView.DataSource = _DataSet; 
                } 
				
                _GridView.DataBind(); 
                nCurrentPage = _GridView.PageIndex + 1; 
                nTotalPage = (_GridView.PageCount > 0 ? _GridView.PageCount : 1); 
            } 
			
            ddlPages.Items.Clear(); 
            ddlPages.Items.Add(new ListItem(Convert.ToString(nPage), Convert.ToString(nPage)));

            for (i = 1; i <= nTotalPage; i++) 
            { 
                if (i != nPage) 
                { 
                    ddlPages.Items.Add(new ListItem(Convert.ToString(i), Convert.ToString(i))); 
                } 
            } 
			
            //Linkbtn狀態判定=================================== 
            lblCurrentPage.Text = Convert.ToString(nCurrentPage); 
            lblTotalPage.Text = Convert.ToString(nTotalPage); 
            lnkFirstPage.Enabled = nCurrentPage != 1; 
            lnkPrePage.Enabled = nCurrentPage != 1; 
            lnkNextPage.Enabled = nCurrentPage != nTotalPage; 
            lnkLastPage.Enabled = nCurrentPage != nTotalPage; 
            //================================================== 
        } 
		
        protected void ddlPageSize_SelectedIndexChanged(object sender, EventArgs e) 
        { 
            _GridView.PageSize = Convert.ToInt32(ddlPageSize.SelectedValue); 
            SetPage("First", true); 
        } 
		
        public PageControl() 
        { 
            Load += Page_Load; Init += Page_Init; 
        } 
		
        protected void lnkFirstPage_Click(object sender, EventArgs e) 
        { 
            SetPage("First", false); 
        } 
		
        protected void lnkLastPage_Click(object sender, EventArgs e) 
        { 
            SetPage("Last", false); 
        } 
		
        protected void lnkPrePage_Click(object sender, EventArgs e) 
        { 
            SetPage("Prev", false); 
        } 
		
        protected void lnkNextPage_Click(object sender, EventArgs e) 
        { 
            SetPage("Next", false);
        } 
    } 
}

畫面結果圖:

結語說明:

Sample Code:Demo_PageUserControl.zip (C# Web 應用程式)

以上是小弟的示範,寫法、觀念上不足之處,請大家見諒,也請大家不吝給予指正。