## 前言
分頁是Web應用程序中最常用到的功能之一,在ASP.NET中,雖然自帶了一個可以分頁的DataGrid和GridView控件,但其分頁功能并不盡如人意,外觀比較丑,是我pass它們的主要原因。而且沒有辦法實現導航與數據顯示的分離。
這個時候AspNetPager針對ASP.NET分頁控件的不足,提出了與眾不同的解決asp.net中分頁問題的方案,即將分頁導航功能與數據顯示功能完全獨立開來,由用戶自己控制數據的獲取及顯示方式,因此可以被靈活地應用于任何需要實現分頁導航功能的地方,因為AspNetPager控件和數據是獨立的,因此要分頁的數據可以來自任何數據源。
## 一、分頁介紹
分頁功能實現從表現形式上分為兩種:真分頁和假分頁。二者各有特色。本篇主要介紹真分頁的實現,這就簡單介紹一下什么是假分頁。
### 1、假分頁:
在第一次請求后,一次性從數據庫中將數據全部取出來,并不全部顯示。而是根據量分為幾個部分,分開呈現在屏幕上。因為是一次性的數據交互動作,顯然,假分頁適用于數據量不大,請求次數少的查詢顯示動作。
### 2、真分頁:
是按查詢數據時給定的查詢記錄數來查多少條數據。通俗的說,要哪里取出哪里。因為取出的數據只是一部分,所以可見真分頁的效率很高。假設你的數據量很大,那么就沒有必要去一次性取出所有的數據。這樣發出命令到web服務器,再返回數據,時間太長了,用戶早就等的不樂意了。這時候就體現出真分頁的優勢了。下面我就以牛腩新聞發布系統為例,介紹一下AspNetPager 控件實現真分頁功能(如圖一)。

[圖一 AspNetPager控件使用效果展示]
## 二、真分頁原理講解
### 1、需要前臺提供什么數據
大家先要考慮一個事情,就是如果實現真分頁的功能,需要怎樣定位我們的數據?答案是一個起始記錄號碼和一個終止號碼。就像是班主任點名字,看著全班的花名冊就會說:請20號到30號的同學到黑板上做題。這里需要從前臺傳遞到后臺BLL層,DAL層,最后到數據庫的存儲過程中的數據就是這個20和30。
### 2、AspNetPager 控件的作用
上一個問題已經解決了“我們需要什么”的問題,下面就是“怎么獲取”的問題,讓AspNetPager干活,它也是需要數據支持的:它要知道一共有多少數據,用戶想讓每一頁顯示幾條記錄。這樣它的第1,2,3,頁的顯示,響應anp_PageChanged的時候實際就是在傳遞行號。
### 3、數據庫中存儲過程的原理
將開始行數和截止行數作為參數傳入存儲過程中,它會根據ID的次序,生成一列行號,這個行號就對應了我們要取得的數據起始標記。如圖二:
****
[圖二 存儲過程執行效果展示]
## 三、代碼實現
1、首先在newsmanager.aspx中添加AspNetPager控件
**控件設置代碼如下:**
~~~
<webdiyer:AspNetPager ID="anp" runat="server" FirstPageText="首頁" LastPageText="尾頁"
? ? ? ? ? ? ? NextPageText="下一頁" OnPageChanged="anp_PageChanged" PageSize="5"
? ? ? ? ? ? ? PrevPageText="上一頁"
? ? ? ? ? ? ? CustomInfoHTML="共%RecordCount%條記錄,共%PageCount%頁 ?"
? ? ? ? ? ? ? ShowCustomInfoSection="Left" ShowPageIndexBox="Never"
? ? ? ? ? ? ? CssClass="paginator" CurrentPageButtonClass="cpb" AlwaysShow="True"
? ? ? ? ? ? ? CustomInfoSectionWidth="">
</webdiyer:AspNetPager>
~~~
2、然后在.cs中傳入數據(U層),因為要多次用到數據的綁定,所以我就把代碼封裝成了一個函數。方便調用。
~~~
protected void Page_Load(object sender, EventArgs e)
{
//判斷session里面是否存在管理員
if (Session["admin"] != null && Session["admin"].ToString() == "zhou")
{
//已登錄
if (!Page.IsPostBack)
{
{
//第一次進入該頁面時
DataTable dt = new DataTable();
dt = new NewsManager().SelectAll();//選擇所有新聞
anp.RecordCount = dt.Rows.Count; //記錄總數
//開始綁定記錄
BindNews();
}
}
}
else
{
//未登錄
Response.Redirect("Default.aspx");
}
}
#region 綁定新聞列表
/// <summary>
/// Repeater控件綁定數據源
/// </summary>
private void BindNews()
{
int startIndex = anp.StartRecordIndex; //開始記錄數
int endIndex = anp.EndRecordIndex; //結束記錄數
repNews.DataSource = new NewsManager().SelectByPage(startIndex, endIndex);
repNews.DataBind();
}
#endregion
protected void anp_PageChanged(object sender, EventArgs e)
{
//控件的切換實現數據庫的數據交互
BindNews();
}
~~~
**3、調用B層**
~~~
#region 分頁功能實現
/// <summary>
/// 分頁控件傳遞開始頁和終止頁的數據
/// </summary>
/// <param name="startIndex">開始數</param>
/// <param name="endIndex">截止數</param>
/// <returns>DataTable</returns>
public DataTable SelectByPage(int startIndex, int endIndex)
{
return ndao.SelectByPage(startIndex, endIndex);
}
#endregion
~~~
**4、調用D層**
~~~
/// <summary>
/// 分頁功能的實現
/// </summary>
/// <param name="startIndex">開始</param>
/// <param name="endIndex">結束</param>
/// <returns></returns>
public DataTable SelectByPage(int startIndex, int endIndex)
{
DataTable dt = new DataTable();
string cmdText = "partPage";
SqlParameter[] paras = new SqlParameter[]{
new SqlParameter ("@startIndex",startIndex ),
new SqlParameter ("@endIndex",endIndex )
};
dt = sqlhelper.ExecuteQuery(cmdText, paras, CommandType.StoredProcedure);
return dt;
}
#endregion
~~~
**5、數據庫中的存儲過程的編寫**
~~~
USE [newssystem]
GO
/****Object: StoredProcedure [dbo].[partPage] Script Date: 2014-11-30 15:38:11 ****/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: 周洲
-- Create date: 2014-11-28
-- Description: 傳入開始號和結束號,查詢新聞
-- =============================================
ALTER PROCEDURE [dbo].[partPage]
@startIndex int, --查詢開始記錄數
@endIndex int --結束記錄數
AS
BEGIN
with temptbl as (
SELECT ROW_NUMBER() OVER (ORDER BY id desc)AS 行號, * from news --使得記錄按順序排列,按行號查詢
)
SELECT * FROM temptbl where 行號 between @startIndex and @endIndex --傳入開始和結束的參數,執行查詢
END
~~~
## 四、總結
AspNetPager作為完全免費且開放源代碼的ASP.NET控件,為Web開發提供了很大的便利。我想起作品展的時候就用到了別人的控件,讓我們省去了很多代碼的編寫。這也算是站在了巨人的肩膀上,用別人封裝好的東西,給我們自己的系統增光添彩。做完了牛腩新聞發布系統為我們掀開了B/S的一個序幕,更多有意思的東西,待我邊探索邊分享。