熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

Asp.Net 可定制分頁用戶控件

2013-11-13 09:40:41  來源: .NET編程 

  介紹
借助 AspNet 提供的數據綁定控件我們無需太多的代碼甚至不需要代碼只要在 VS 中拖拽幾下控件進行一些屬性的設置便可以實現在Asp時代需要做大量工作才能夠實現的分頁功能但在實際的應用中尤其是在Web站點程序中我們經常需要更加豐富的用戶界面而類似DataList或者 GridView 這樣的數據控件往往不能或者很難滿足我們的要求此時我們常常求助於 Repeater 控件這樣我們依舊會面臨分頁及其顯示的問題

  本文不是講述如何進行數據庫分頁而將注意力集中在如何實現可定制地 獲取頁碼獲取路徑顯示分頁鏈接並且通過構建一個用戶控件來實現代碼重用上如果你是一個初學者你可以借鑒一下我的實現方式如果你已經是一位高手不妨提出設計的不足和改進意見

  NOTE本文是以接口的實現方式作為講述這是因為我寫這篇文章的時候使用的是接口但我後來又提供了一種更好的使用繼承的方式來實現我提供了兩個版本的代碼下載你可以相互對比著參考

  控件組成
為了能迅速提起大家的興趣可以先點擊這個鏈接看看實際的效果

  x

  IUrlManager 接口
想一想如果你在設計一個可重用的分頁用戶控件你面臨的問題是什麼每個人獲取頁碼的方式都不同例如你的站點URL可能是類似這樣的 Defaultaspxpage= 而另外一個站點的URL 是這樣的 Defaultaspxp=更有一些可能根本不使用 QueryString 來獲取頁碼它們的URL可能是這樣的 DefaultaspxDefaultaspx 等等獲取頁碼的方式不同根據頁碼產生鏈接地址的方法自然也不相同按照封裝變化的思想我們應該將這變化的部分取出來建一個 IUrlManager 接口

  public interface IUrlManager
{
int CurrentPageIndex{ get; } // 當前頁碼
string GetPageUrl(int pageIndex); // 根據 頁碼 獲取頁面路徑
}

  而實際上當前頁碼不應該大於總頁數所以獲取當前頁CurrentPageIndex屬性需要能得知 總頁數而總頁數通常是由 記錄數 和 分頁大小計算得出這個接口實際上應該是這樣

  public interface IUrlManager
{
int CurrentPageIndex{ get; } // 當前頁碼
string GetPageUrl(int pageIndex); // 根據 頁碼 獲取頁面路徑
int PageCount { get; } // 總頁數

  int RecordCount { get; } // 記錄總數
int PageSize { get; } // 分頁大小
}

  要求在 IUrlManager裡實現總頁數PageCount屬性可能有點奇怪但仔細想一想就明白了

  控件本身需要知道總共有多少頁然後才能判斷顯示多少鏈接數我們的用戶控件部分僅僅是進行一系列鏈接的顯示它僅需要知道 當前頁碼總頁碼以及鏈接的URL 就足夠了 因為 當前頁碼 應該小於等於 總頁碼所以獲取當前頁碼 CurrentPageIndex 也需要知道 總頁碼 而為什麼要實現 RecordSize 和 PageSize 屬性是一個值得思考的地方

  總頁碼 是根據 記錄數 和 分頁大小 算得的所以對於實現 IUrlManager 接口的類我們總是需要提供 記錄數 和 分頁大小何不簡單地提供一個屬性來對它們進行訪問而其他的地方(比如某個方法)有可能會需要這兩個值此時我們可以直接將 IUrlManager 作為參數傳進去

  問題是如果這個接口僅僅是用於 分頁控件那麼實現 RecordSize 和 PageSize 是不必要的我們也不應該在控件上設置 RecordCountPageSize這裡的粒度可能大了

  DefaultUrlManager 類
現在 所有獲取頁碼 及 根據頁碼獲取路徑 的邏輯都可以放在實現了這個接口的類中如果你想使用這個控件你需要提供一個實現了IUrlManger接口的類為了使控件立即可用我在這裡提供了一個默認實現我管它叫做 DefaultUrlManger它通過RequestQueryString獲取頁碼並默認以Page作為參數

  public class DefaultUrlManager : IUrlManager {
private HttpContext context;
private Regex reg;
private string queryParam; // QueryString 參數名稱
private int currentPageIndex; // 當前頁
private int pageCount; // 總頁數
private int recordCount; // 記錄總數
private int pageSize; // 分頁大小

  // 構造函數
public DefaultUrlManager(int recordCount int pageSize string queryParam)
{
if (recordCount < )
throw new ArgumentOutOfRangeException(recordCount 應該大於等於 !);
if (pageSize < = )
throw new ArgumentOutOfRangeException(pageSize 應該大於 );
if (stringIsNullOrEmpty(queryParam))
throw new ArgumentNullException(queryParam 不能為空!);

  // 設置私有變量
thisrecordCount = recordCount;
thispageSize = pageSize;
thisqueryParam = queryParam;
context = HttpContextCurrent;
string pattern = @(< r>[&] + queryParam + @=)[^&]*;
reg = new Regex(pattern RegexOptionsIgnoreCase);

  // 如果記錄數為至少也顯示一頁
if (recordCount == ) {
currentPageIndex = ;
pageCount = ;
} else {

  // 設置總頁數
double recordCount = ConvertToDouble(recordCount);
double pageSize = ConvertToDouble(pageSize);
pageCount = ConvertToInt(MathCeiling(recordCount / pageSize));

  // 設置當前頁碼
string queryIndex = contextRequestQueryString[queryParam];

  if (stringIsNullOrEmpty(queryIndex))
currentPageIndex = ;
else {
try {
currentPageIndex = MathAbs(intParse(queryIndex));

  if (currentPageIndex == )
currentPageIndex = ;
if (currentPageIndex > pageCount)
currentPageIndex = pageCount;
}
catch {
currentPageIndex = ;
}
}
}
}

  // 默認以 Page 作為 QueryString 的參數
public DefaultUrlManager(int recordCount int pageSize) : this(recordCount pageSize Page) { }

  // 默認以 作為 PageSize
public DefaultUrlManager(int recordCount string queryParam) : this(recordCount queryParam) { }

  // 默認以 Page 作為 QueryString 的參數 作為分頁大小
public DefaultUrlManager(int recordCount) : this(recordCount ) { }

  public string GetPageUrl(int pageIndex) {
string pageUrl = contextRequestRawUrl;

  // 如果找到匹配也就是URL中含有類似 page= 或者 &page= 這樣的字符串

  // 則對後面的數值進行替換
if (regIsMatch(pageUrl)) {
pageUrl = regReplace(pageUrl ${r} + pageIndexToString());
} else {

  string queryString = contextRequestUrlQuery;

  if (stringIsNullOrEmpty(queryString))
pageUrl += + queryParam + = + pageIndexToString();
else
pageUrl += & + queryParam + = + pageIndexToString();
}

  return pageUrl;
}

  public int CurrentPageIndex
{
get { return currentPageIndex; }
}

  public int PageCount
{
get { return pageCount; }
}

  public int RecordCount
{
get { return recordCount; }
}

  public int PageSize
{
get { return pageSize; }
}
}

  Pagerascx 文件
由於我們的鏈接是動態生成的所以我們大部分的代碼都會存在於 Pagerascxcs 中在Pagerascx 文件中我們只提供一個裝鏈接的


From:http://tw.wingwit.com/Article/program/net/201311/11307.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.