一前言
GridView中的分頁是用post做的所以將查詢表單中的內容可以存到ViewState中翻頁的時候可以利用實現起來就比較容易些而在mvc中這些就要我們自己來做了Contrib中的分頁只能應付簡單應用對於查詢後結果的分頁沒做處理下面我們來改造一下這個分頁程序
二准備工作
首先准備一個數據源
數據源准備
public class News
{
public int ID { get; set; }
public string Author { get; set; }
public string Title { get; set; }
public DateTime CreateTime { get; set; }
}
public class ListNews
{
public static List<News> GetList()
{
List<News> list = new List<News>();
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNow });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNowAddHours() });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNowAddHours() });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNowAddHours() });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNowAddHours() });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNow });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNowAddHours() });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNowAddHours() });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNowAddHours() });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNowAddHours() });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNowAddHours() });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNow });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNowAddHours() });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNow });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNowAddHours() });
listAdd(new News { ID = Author = lfm Title = 中華人民共和國周年 CreateTime = DateTimeNow });
return list;
}
}
然後添加一個View
View
<%HtmlBeginForm();%>
Title:<%=HtmlTextBox(titleRequestForm[title]??RequestQueryString[title]) %>
Author:<%=HtmlTextBox(authorRequestForm[author]??RequestQueryString[author]) %>
<input type=submit value=查詢 />
<%HtmlEndForm(); %>
<%=HtmlGrid(Model)Columns(column=>{
columnFor(x=>xID)Named(News ID);
columnFor(x => HtmlActionLink(xTitle NewsDetils new { newsId = xID }))DoNotEncode();
columnFor(x => xAuthor)Header(<th>+HtmlActionLink(作者CustomPagernew{desc = ConvertToBoolean(ViewData[desc])sortName=Author})+</th>);
columnFor(x=>xCreateTime);
})
%>
<%= HtmlPager(ModelViewData[search])%>
這裡的分頁代碼和Contrib中略有不同一會兒我們來講解這個不同的原因
添加一個Controller
Controller
public ActionResult CustomPager(int? page)
{
int pageSize = ;
int pageNumber = page ?? ;
var list = ListNewsGetList()
Where(p => pTitleContains(RequestQueryString[title] ?? ))
Where(p => pAuthorContains(RequestQueryString[author] ?? ));
var pageList=listSkip((pageNumber ) * pageSize)Take(pageSize);
int total = listCount();
CustomPagination<News> customes = new CustomPagination<News>(pageList pageNumber pageSize total);
return View(customes);
}
[AcceptVerbs(HttpVerbsPost)]
public ActionResult CustomPager(FormCollection formCollection)
{
int pageSize = ;
int pageNumber = ;
var list = ListNewsGetList()Where(p => pTitleContains(RequestForm[title]))
Where(p => pAuthorContains(RequestForm[author]));
int total = listCount();
var pageList = listSkip((pageNumber ) * pageSize)Take(pageSize);
CustomPagination<News> customes = new CustomPagination<News>(pageList pageNumber pageSize total);
Dictionary<string string> d = new Dictionary<string string>();
dAdd(title RequestForm[title]);
dAdd(author RequestForm[author]);
ViewData[Search] = d;
return View(customes);
}
注這部分內容的詳細講解可以參見ASPNET MVC實踐系列Grid實現(下利用Contrib實現)
三Contrib的分頁源碼分析
我們先把Pagination和Pager兩個文件夾中的源碼copy出來經過分析我們知道CustomPagination是實現了IPagination接口的集合我們把數據整合到CustomPagination中就可以使用Pager進行分頁了PaginationExtensions是輔助HtmlHelper使用擴展方法的靜態類
四Pager類改造
經過分析我們發現Pager是通過ToString()方法將分頁字符串輸出到前台的所以我們這裡需要先改造Pager的ToString()方法我們常常希望分頁是這樣顯示的
上一頁 下一頁所以先將ToString()方法改造如下
ToString方法
public override string ToString()
{
if (_paginationTotalItems == )
{
return null;
}
var builder = new StringBuilder();
builderAppend(<div class= + _pageStyle + >);
if (_paginationPageNumber > )
builderAppend(CreatePageLink(_paginationPageNumber _pagePrev));
else
builderAppend(CreatePageText(_pagePrev));
for (int i = ; i < _paginationTotalPages; i++)
{
var current = i + ;
if (current == _paginationPageNumber)
{
builderAppend(CreatePageText(currentToString()));
}
else
{
builderAppend(CreatePageLink(current currentToString()));
}
builderAppend( );
}
if (_paginationPageNumber < _paginationTotalPages)
builderAppend(CreatePageLink(_paginationPageNumber + _pageNext));
else
builderAppend(CreatePageText(_pageNext));
builderAppend(@</div>);
return builderToString();
}
這裡需要交代一下將要實現查詢分頁的原理這個方案中我們將會把查詢的信息附加到分頁的Url上首先我們會把需要附加的條件添加到一個Dictionary<string string>類中然後傳給Pager類進行處理
下面我們來改造一下CreateQueryString方法
CreateQueryString
private string CreateQueryString(NameValueCollection values)
{
var builder = new StringBuilder();
if (_searchValues != null)
{
builder = GetSearchPage(values);
}
else
{
foreach (string key in valuesKeys)
{
if (key == _pageQueryName)
//Dont readd any existing page variable to the querystring this will be handled in CreatePageLink
{
continue;
}
foreach (var value in valuesGetValues(key))
{
builderAppendFormat(&{}={} key HttpUtilityUrlEncode(value));
}
}
}
return builderToString();
}
/// <summary>
/// 根據傳入的_searchValues來組織分頁字符串
/// </summary>
/// <param name=values></param>
/// <returns></returns>
private StringBuilder GetSearchPage(NameValueCollection values)
{
var builder = new StringBuilder();
Dictionary<string string> dictionary = new Dictionary<string string>();
foreach (var item in _searchValues)
{
dictionaryAdd(itemKey itemValue);
}
foreach (string key in valuesKeys)
{
if (key == _pageQueryName)
//Dont readd any existing page variable to the querystring this will be handled in CreatePageLink
{
continue;
}
foreach (var value in valuesGetValues(key))
{
if (_searchValuesKeysContains(key))
{
builderAppendFormat(&{}={} key HttpUtilityUrlEncode(dictionary[key]));
dictionaryRemove(key);
}
else
{
builderAppendFormat(&{}={} key HttpUtilityUrlEncode(value));
}
}
}
foreach (var item in dictionary)
{
builderAppendFormat(&{}={} itemKey HttpUtilityUrlEncode(itemValue));
}
return builder;
}
這裡邊主要添加的就是這個GetSearchPage方法這個方法就是根據客戶端傳入的查詢條件來組織顯示分頁字符串的
五缺點
因為時使用附加url的方式實現的所以對於查詢條件過多的時候可能有問題有空我會再實現一個post方案供大家參考另外這裡大家還需要注意的就是url中的查詢字符串的名字不能重復如果重復會直接被替換詳見源碼
六源碼
From:http://tw.wingwit.com/Article/program/ASP/201311/21723.html