分頁是WEB開發中面對的最常見的編程,實現方法多種多樣。但是多數都太複雜,不夠清晰不夠簡單也不物件導向.而下面提供這種分頁方法不僅簡單,而且高效,複用性也很好
這種分頁的思路是這樣的:
1、把分頁後的資料抽象為一個類,你可以把它想象成一個雙向鏈表的一個結點。
結構如下:
[複製到剪貼簿]
CODE:
//頁類
public class Page
{
public int pageno { get; set; }//頁號
public int from { get; set; }//前一頁號
public int to { get; set; }//後一頁號
public IList<object> result { get; set; }//資料
public Page(int page)
{
this.pageno = page;
}
}
2、編寫一個Pager類來管理根據你的資料來源計算總頁碼、當前頁碼的資料、產生用於導航的頁碼條。
[複製到剪貼簿]
CODE:
using System;
using System.Collections.Generic;
using System.Text;
public class Pager
{
int total_pages = 1;
int elem_per_page = 10;
int count_elements = 0;
IList<object> arr = new List<object>();
//建立函數
public Pager(IList<object> arr, int per_page)
{
elem_per_page = per_page;
count_elements = arr.Count;
if ((this.count_elements % per_page) == 0)
{
total_pages = (int)(count_elements / per_page);
}
else
{
total_pages = (int)(count_elements / per_page) + 1;
}
this.arr = arr;
}
//計算出一頁來
public Page page(int pageno)
{
Page apage = new Page(pageno);
int from = this.elem_per_page * (pageno - 1) + 1;
int to = from + this.elem_per_page - 1;
if (to > count_elements) { to = this.count_elements; }
List<object> res = new List<object>();
for (int i = (from - 1); i < to; i++)
{
res.Add(this.arr[i]);
}
apage.from = from;
apage.to = to;
apage.result = res;
return apage;
}
//簡單地產生頁碼
public string PrintPageNumbers(int cp, string url)
{
string pageurl = "<div id=\"paperindex\">";
if (url.Contains("?")) { url += "&pageno="; } else { url += "?pageno="; }
for (int i = 1; i < this.total_pages + 1; i++)
{
if (i != cp)
{
pageurl = pageurl + "[<a href=\"" + url + "" + i + "\">" + i + "</a>]";
}
else
{
pageurl = pageurl + "<span id=\"current\">[" + i + "]</span>";
}
}
return pageurl + "</div>";
}
}
簡單分析一下,建立函數根據每頁顯示資料條數計算出總頁數,根據你取得的頁碼調用page(int)來取得那一頁的page執行個體,page執行個體中包含它的頁碼,它上一頁和下一頁的頁碼,和分頁完成後的資料。應用PrintPageNumbers()函數你就可以得到一個用於導航的索引條了。
3、使用方法
IList<object> list=BLL.News.getAll();//從業務層取資料
Pager pager=new Pager(list,20);//從list取資料進行分頁,每頁20條.
Page ap=pager.page(Int32.Parse(Request["pageno"]));//以GET方式擷取需要顯示的頁號。
Label1.Text=pager.PrintPageNumbers(Int32.Parse(Request["pageno"]), Request.FilePath.ToString());//向介面上寫出導航條
因為ap.result儲存著分頁後的資料,我們顯示資料就有很多選擇了。如果你是用table表達那你迴圈一下拆箱後把每個對象的屬性輸出一下,如果是用AJAX表達那你把對象列錶轉換成JSON或XML,傳給AJAX頁面。OK。分頁達成。
4、擴充
如果你需要更漂亮的導航,可以覆寫Pager類的PrintPageNumbers方法,我們對它進行擴充非常的容易。比如為實現以下效果。
每次只顯示5個頁碼,根據頁碼值來判斷是否需要加上最前頁等連結。如。
我給Pager類加了以下的產生分頁導航的函數。
[複製到剪貼簿]
CODE:
#region 後面是可擴充的頁碼顯示方式,我實現了其它兩種。
/**
* 產生前置串
* 根據當前頁號來產生是否有上一頁或最前頁
* */
public string get_prestr(int pageindex, string url)
{
string result = "<div id=\"paperindex\">";
if (url.Contains("?")) { url += "&pageno="; } else { url += "?pageno="; }
if (pageindex > 1)
{
if (pageindex >= 3)//從第三頁起顯示 « «上一頁
{
result += "<a href=\"" + url + "1\">最前頁</a>,<a href=\"" + url + (pageindex - 1) + "\">上一頁</a>,";
}
else//第2頁顯示 «上一頁
{
result += "<a href=" + url + (pageindex - 1) + ">上一頁</a>,";
}
}
else
{
}
return result;
}
/**
* 產生中間數字串
* 如總記13頁當前頁為5,每次顯示5個頁碼
* 則應該返回3,4,5,6,7
* */
public List<int> get_midpageno(int pageindex, int display_count)
{
List<int> l = new List<int>();
int A = display_count / 2;//取中間值
if (total_pages > display_count)
{
if (pageindex <= A)
{
for (int i = 1; i < display_count + 1; i++)
{
l.Add(i);
}
}
if (pageindex > (total_pages - A))
{
for (int i = total_pages - display_count + 1; i < total_pages + 1; i++)
{
l.Add(i);
}
}
if ((pageindex > A) && (pageindex <= (total_pages - A)))
{
for (int i = pageindex - A; i < pageindex + A + 1; i++)
{
l.Add(i);
}
}
}
else
{
for (int i = 1; i < total_pages + 1; i++)
{
l.Add(i);
}
}
return l;
}
/**
* 產生後導串
* 根據當前頁碼和總頁碼來判斷是否顯示最後頁和後一頁
* */
public string get_nextstr(int pageindex, string url)
{
//與前置串演算法類似,所以先計算當前頁是倒數第幾頁
int toend = total_pages - pageindex + 1;
string result = "";
if (url.Contains("?")) { url += "&pageno="; } else { url += "?pageno="; }
if (toend > 1)
{
if (toend >= 3)//從倒數第三頁起顯示 下一頁» »
{
result += "<a href=\"" + url + (pageindex + 1) + "\">下一頁</a>,<a href=\"" + url + total_pages + "\">最後頁</a> ";
}
else//倒數第2頁顯示 下一頁»
{
result += "<a href=" + url + (pageindex + 1) + ">下一頁</a>";
}
}
else
{
}
return result + "</div>";
}
/*
* 一種產生固定顯示頁碼數量的頁碼display_count最好是個奇數,這樣可以保證當前頁處於分頁條的正中間
* 產生的頁碼以一個ID為paperindex的div封裝,當前頁碼ID為current,方便載入樣式。
* */
public string PrintPageNumbers(int pageindex, string url, int display_count)
{
string originurl = url;
string pageurl = "";
if (url.Contains("?")) { url += "&pageno="; } else { url += "?pageno="; }
pageurl += get_prestr(pageindex, originurl);//加入前置串
//產生中間串
foreach (int a in get_midpageno(pageindex, display_count))
{
if (a.Equals(pageindex))
{
pageurl += "<span id=\"current\">" + a + "</span>,";
}
else
{
pageurl += "<a href=\"" + url + a + "\">" + a + "</a>,";
}
}
pageurl += get_nextstr(pageindex, originurl);//加入後導串
if (pageurl.EndsWith(",</div>")) { pageurl = pageurl.Replace(",</div>", "</div>"); }
return pageurl;
}
//顯示總記錄數和總頁數
public string PrintPageNumbers(int pageindex, string url, int display_count, bool todisplaytotalrecorder, bool todisplaytotalpages)
{
string result = "";
if (todisplaytotalrecorder) { result += "<span id=\"recordercount\">共有記錄:" + this.arr.Count + "條</span> "; }
if (todisplaytotalpages) { result += "<span id=\"pagecount\">共記:" + this.total_pages + "頁</span>"; }
return result + PrintPageNumbers(pageindex, url, display_count);
}
#endregion
在調用這個函數產生的導航表達索引時,需要再配合一下簡單的樣式表。因為我在輸出頁碼時給它加了ID屬性,所以可以根據ID載入CSS。
CSS:
[複製到剪貼簿]
CODE:
<style type="text/css">
#paperindex{
font:14px #000000;
}
#paperindex #current{
border:1px solid #142A3B;
background-color:B1D3EC;
color:#000;
}
a,a:visited
{
text-decoration:none;
color:#000;
}
a:hover
{
color:red;
text-decoration:underline;
}
</style>
DEMO:
List<object> list=BLL.Customers.getAll();//從業務層或資料層取出資料列表
Pager pager = new Pager(list, 20);//產生pager,資料從list中取,每頁20條
int currentpageindex=Int32.parse(Request["pageno"]);//GET方式擷取pageno,pageno是類中定義的頁碼傳參變數
Page page = pager.page(currentpageindex);//然後就可以通過page.result來取到用於顯示的當前頁的List<object>資料
再通過Pager的PrintPageNumbers方法來產生頁碼的字串。