前言:
分頁,大伙并不陌生
也許你正用著:DataGrid/GridView自帶的分頁
也許你正用著:網(wǎng)上流傳較廣的AspnetPager分頁控件
也許你正用著:其它同事寫的分頁控件
又也許:你正是那個寫分頁控件的人,如果是,現(xiàn)在的你是否回頭看過自己當(dāng)初的源碼?感覺?
附言:
昨夜,花了兩個小時左右,把一個2007年那會寫的分頁控件,重新優(yōu)化改造了一下:
cs代碼大小從原來的14K,縮減到4K。
原來的分頁控件源碼:點擊下載 在看以下正文之前,還是希望能看一下原來的分頁控件的源碼,這樣才能感嘆下改造前后的巨大落差。
正文:
一:概述
目前分頁控件,據(jù)個人所知的,有幾下幾種實現(xiàn)情況:
1:Post篇 [生成N個按鈕,每個按鈕點擊時產(chǎn)生一個Post事件引發(fā)分頁]
常見方式:控件實現(xiàn)復(fù)雜,內(nèi)滲雜sql語句。
本文方式:反射機制,與sql無關(guān)。
遙想當(dāng)年是配合了atlas的updatepanel實現(xiàn)的無刷新
2:Get篇 [生成N個鏈接,每個鏈接點擊時產(chǎn)生一個Get事件引發(fā)分頁]
方式一:鏈接分頁,常見于參數(shù)后面的page=N
方式二:鏈接分頁,Url重寫,常見于url參數(shù)為 /page/N
方式三:腳本分頁,無刷新,鏈接都采用onclick="js函數(shù)"引發(fā)ajax回調(diào)異步分頁。
二:實現(xiàn)
在具體寫實現(xiàn)代碼之前,我們上幾張圖片看一下效果:
說明:
夜把代碼上傳到網(wǎng)絡(luò)空間時,忘了把樣式也傳上去,早上下載后發(fā)現(xiàn)沒樣式。
所以樣式是自己臨時加上去的,大伙自己感知一下效果了就可以了。
下面開始分頁控件實現(xiàn)具體步驟:
1:新建一個用戶控件:Pager
2:控件前臺html
<table id="pager" border="0" cellpadding="0" cellspacing="0" width="100%">
<asp:LinkButton ID="lbtnFirstLink" runat="server" CausesValidation="false" OnClick="ClickEvent">首頁
<asp:LinkButton ID="lbtnPrevPage" runat="server" CausesValidation="false" OnClick="ClickEvent">上一頁
<asp:Repeater ID="rptNum" runat="server" OnItemCommand="rptNum_ItemCommand">
<asp:LinkButton ID="lbtnNum" runat="server" CausesValidation="false" CommandArgument='<%# Container.DataItem %>'
CssClass='<%# Convert.ToInt32(Container.DataItem)==PageIndex?"num_yellow":"num_blue"%>' Width="15"><%# Container.DataItem %>
<asp:LinkButton ID="lbtnNextPage" runat="server" CausesValidation="false" OnClick="ClickEvent">下一頁
<asp:LinkButton ID="lbtnLastPage" runat="server" CausesValidation="false" OnClick="ClickEvent">尾頁
<asp:HiddenField ID="hfBindName" runat="server" />
說明:
A:用了表格布局,簡單,想換div的自己改了。B:用了五個LinkButton,其中數(shù)字的一個用Repeater循環(huán)N個數(shù)字出來
C:最后加了一個隱藏域,用于保存綁定的方法名稱。
D:數(shù)字里有兩個樣式用于為數(shù)字賦樣式,樣式到示例時再寫出來吧 E:首頁/上一頁/下一頁/尾頁,用的點擊事件都是同一個函數(shù)。 F:Repeater有個OnItemCommand事件,點擊數(shù)字要重新綁定的。
3:后臺cs代碼
A:幾個屬性
nbsp; private int _PageIndex;
public int PageIndex
{
get{if (_PageIndex == 0){ _PageIndex = 1;}return _PageIndex;}
set{ _PageIndex = value;}
}
private int _PageSize;
public int PageSize
{
get{if (_PageSize == 0){_PageSize = 1;}return _PageSize;}
set{ _PageSize = value;}
}
private int _Count;
public int Count
{
get{return _Count; }
set { _Count = value; }
}
///
/// 該方法名稱修飾符為需為public
///
public string BindName
{
get{return hfBindName.Value;}
set{hfBindName.Value = value; }
}
說明:
PageIndex:第幾頁
PageSize:每頁多少條
Count:記錄總數(shù)
BindName:綁定的方法名稱,用于反射綁定數(shù)據(jù)
B:Page_Load做點什么
private void Page_Load(object sender, System.EventArgs e)
{
if (!Page.IsPostBack)
{
BindPager();//綁定分頁數(shù)字
}
}
說明:
第一次綁定時,界面已實現(xiàn)綁定數(shù)據(jù),所以只需要綁定分頁的數(shù)字就行
C:綁定分頁數(shù)字
public void BindPager()
{
int pageCount = (Count % PageSize) == 0 ? Count / PageSize : Count / PageSize + 1;//頁數(shù)
SetButtonEnable(pageCount);//下面四個按鈕可用狀態(tài)設(shè)置
BindPageNum(pageCount);//綁定循環(huán)數(shù)字
}
說明:
1:從記錄總數(shù)和頁面大小計算出有多少頁,這個少不的。
2:根據(jù)當(dāng)頁的頁數(shù)和當(dāng)前頁面索引,設(shè)置下“首頁/下一頁/上一頁/尾頁”的可用狀態(tài)
3:根據(jù)當(dāng)前的頁數(shù)綁定一下循環(huán)的數(shù)字。
函數(shù)分解:SetButtonEnable [設(shè)置按鈕可用狀態(tài)及參數(shù)賦值]
private void SetButtonEnable(int pageCount)
{
lbtnFirstLink.Enabled = PageIndex != 1;
lbtnPrevPage.Enabled = PageIndex != 1;
lbtnNextPage.Enabled = PageIndex != pageCount;
lbtnLastPage.Enabled = PageIndex != pageCount;
lbtnFirstLink.CommandArgument = "1";
lbtnPrevPage.CommandArgument = (PageIndex - 1).ToString();
lbtnNextPage.CommandArgument = (PageIndex + 1).ToString();
lbtnLastPage.CommandArgument = pageCount.ToString();
}
說明:
1:如果當(dāng)前頁為第1頁:首頁/上一頁狀態(tài)不可用
2:如果當(dāng)前頁為最后1頁:下一頁/尾頁狀態(tài)不可用
3:順路把幾個頁索引值賦給CommandArgument
函數(shù)分解:BindPageNum [綁定分頁數(shù)字]
protected void BindPageNum(int pageCount)
{
int start = 1, end = 10;
if (pageCount < end)//頁數(shù)小于10
{
end = pageCount;
}
else
{
start = (PageIndex > 5) ? PageIndex - 5 : start;
int result = (start + 9) - pageCount;//是否超過最后面的頁數(shù)
if (result > 0)
{
end = pageCount;
start -= result;//超過后,補差
}
else
{
end = start + 9;
}
}
ReBindNum(start, end);
}
說明:
1:由于綁定的數(shù)字,在往后頁數(shù)點擊時,頁數(shù)數(shù)字需要進(jìn)行變化,所以需計算好開始數(shù)字和結(jié)束數(shù)字
2:根據(jù)開始數(shù)字和結(jié)束數(shù)字進(jìn)行綁定
函數(shù)分解:ReBindNum [循環(huán)綁定數(shù)字]
private void ReBindNum(int start, int end)
{
int[] rows = new int[10];
int index = 0;
for (int i = start; i <= end; i++)
{
rows[index] = i;
index++;
}
rptNum.DataSource = rows;
rptNum.DataBind();
}
說明:
1:這里用int[]數(shù)組循環(huán)數(shù)字來綁定到Repeater
2:界面綁定用<%# Container.DataItem %>方式進(jìn)行對應(yīng)
D:反射綁定[簡潔重點函數(shù)]
private void ReBindData(string pageIndex)
{
PageIndex = int.Parse(pageIndex);
object obj = base.Parent is HtmlForm ? this.Page : base.Parent;
MethodInfo mi = obj.GetType().GetMethod(BindName);
mi.Invoke(obj,null);
BindPager();
}
說明:
2:獲取綁定數(shù)據(jù)的方法,重新調(diào)用一下
3:重新綁定分布數(shù)字
F:首頁/上一頁/下一頁/尾頁,按鈕事件
protected void ClickEvent(object sender, EventArgs e){
ReBindData(((LinkButton)sender).CommandArgument.ToString());
}
G:分頁數(shù)字,按鈕事件
protected void rptNum_ItemCommand(object source, RepeaterCommandEventArgs e){
ReBindData(e.CommandArgument.ToString());
}
三:示例代碼,和 CYQ.Data輕量數(shù)據(jù)層框架 配合使用
1:html代碼
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="PagerDemo.aspx.cs" Inherits="PagerDemo" EnableTheming="false" %>
<%@ Register Src="UserControls/Pager.ascx" TagName="Pager" 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">
<style type="text/css">
#pager {color:White;}
#pager a{color:White;text-decoration:none; }
.num_blue{color:White;border:solid 1px Blue;text-align:center;}
.num_yellow{color:while;border:solid 1px Yellow; text-align:center;}
<body style="background-color:Black;color:White;">
<form id="form1" runat="server">
<uc1:Pager ID="Pager1" runat="server" />
2:后臺代碼
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadData();
}
}
public void LoadData()
{
int count;
MAction action = new MAction(TableNames.Users);
MDataTable mTable = action.Select(Pager1.PageIndex, Pager1.PageSize, "", out count);
action.Close();
gvUsers.DataSource = mTable;
gvUsers.DataBind();
Pager1.BindName = "LoadData";
Pager1.Count = count;
}
說明:
1:BindName為綁定數(shù)據(jù)的方法名稱,該方法名稱的修飾符號需為public
2: 默認(rèn)的分頁PageSize可自行修改默認(rèn)值
3: 前面html也可設(shè)置為:<uc1:Pager ID="Pager1" runat="server" PageSize="20" />
3:最終效果
如正文一開始發(fā)的五張圖片一致
結(jié)言:
以上教程中,以包含所有代碼,包括前后臺,所以不另提供打包下載。
有興趣的來客歡迎討論留言。