Asp.net MVC 使用PagedList(新的已更名 為X.PagedList.Mvc) 分頁


在asp.net mvc 中,可以bootstrap來作為界面,自己來寫分頁程序。也可以使用PagedList(作者已更名為 X.PagedList.Mvc)來分頁。

1、首先,在NuGet程序包管理控制台 ,輸入Install-Package PagedList.mvc 安裝PagedList 和PageList.Mvc;查看程序中的引用,已經有了PagedList,和PagedList.Mvc兩個文件的引用

2、使用PagedList,下面是微軟官方的一個實現了排序、查找、分頁功能的例子。通過多設置一個查找變量參數來保存當時的查找字符串 currentFilter,,分頁、排序的時候都使用currentFilter來作為參數傳遞。而一旦在 UI中重新輸入查找字符串,就將頁碼設置為第一頁。

控制器代碼:

using PagedList;

public ActionResult Index(string sortOrder,string currentFilter,string searchString,int? page)
{
ViewBag.CurrentSort = sortOrder;

ViewBag.FirstNameSortParam = string.IsNullOrEmpty(sortOrder) ? "FirstName_desc" : "";
ViewBag.LastNameSortParam = sortOrder == "LastName" ? "LastName_desc" : "LastName";
ViewBag.DateSortParam = sortOrder == "date" ? "date_desc" : "date";

var students = from s in db.Students
select s;

if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}

ViewBag.CurrentFilter = searchString;

if (!string.IsNullOrEmpty(searchString))  //注意,判斷字符串類型為空,要使用String.IsNullEmpty() 而不能使用 !=null 來判斷。
{
students= students.Where(s => s.LastName.ToUpper() .Contains(searchString.ToUpper())
|| s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
}
//ViewBag.searchString = searchString;

switch (sortOrder)
{
case "FirstName_desc":
students = students.OrderByDescending(s => s.FirstMidName);
break;
case "LastName":
students = students.OrderBy(s => s.LastName);
break;
case "LastName_desc":
students = students.OrderByDescending(s => s.LastName);
break;
case "date":
students =students.OrderBy(s =>s.EnrollmentDate);
break;
case "date_desc":
students = students.OrderByDescending(s => s.EnrollmentDate);
break;
default:
students = students.OrderBy(s => s.FirstMidName);
break;
}

int pageSize = 2;
int pageNumber = (page ?? 1);

return View(students.ToPagedList(pageNumber,pageSize));
}

視圖代碼:

@model PagedList.IPagedList<ContosoUniversity.Models.Student>
@using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
@{
ViewBag.Title = "學生";
}

<h2>@ViewBag.Title</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>
@using (Html.BeginForm("Index", "Student", FormMethod.Get, new { @class="form-inline",role="form" }))
{
<label for="searchString" class="control-label">通過名字查找:</label>
<div class="form-group">
@Html.TextBox("searchString", ViewBag.CurrentFilter as string, htmlAttributes: new { @class = "form-control", placeholder = "請輸入名字" })   //只是在文本框中回顯當時查找的字符串,並沒 將 name為searchString的文本框表單提交
</div>

<input type="submit" value="查找" class="btn btn-primary" />
}
<table class="table table-hover table-striped">
<thead>
<tr>
<th>
@Html.ActionLink("名", "Index", new { sortOrder = ViewBag.LastNameSortParam, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
@Html.ActionLink("姓", "Index", new { sortOrder = ViewBag.FirstNameSortParam, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
@Html.ActionLink("入學時間", "Index", new { sortOrder = ViewBag.DateSortParam, currentFilter = ViewBag.CurrentFilter })
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.FirstMidName)
</td>
<td>
@Html.DisplayFor(modelItem => item.EnrollmentDate)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
@Html.ActionLink("Details", "Details", new { id = item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.ID })
</td>
</tr>
}
</tbody>
</table>
<br />
Page @(Model.PageCount< Model.PageNumber ? 0: Model.PageNumber)of @Model.PageCount

@Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))

 

二、也可使用可選參數來指定page參數值為1,這樣在index方法中就少一個保存當前查詢的字符串參數值了。這樣更為簡潔易懂,特別適用於多個查詢字符或多個下拉框選擇的情況。

控制器代碼:

using PagedList;

public ActionResult Index(string sortOrder,string searchString,int page =1) //使用可選參數 page默認值為1.
{
ViewBag.CurrentSort = sortOrder;

ViewBag.FirstNameSortParam = string.IsNullOrEmpty(sortOrder) ? "FirstName_desc" : "";
ViewBag.LastNameSortParam = sortOrder == "LastName" ? "LastName_desc" : "LastName";
ViewBag.DateSortParam = sortOrder == "date" ? "date_desc" : "date";

var students = from s in db.Students
select s;

 

ViewBag.SearchString = searchString;

if (!string.IsNullOrEmpty(searchString))
{
students= students.Where(s => s.LastName.ToUpper() .Contains(searchString.ToUpper())
|| s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
}
//ViewBag.searchString = searchString;

switch (sortOrder)
{
case "FirstName_desc":
students = students.OrderByDescending(s => s.FirstMidName);
break;
case "LastName":
students = students.OrderBy(s => s.LastName);
break;
case "LastName_desc":
students = students.OrderByDescending(s => s.LastName);
break;
case "date":
students =students.OrderBy(s =>s.EnrollmentDate);
break;
case "date_desc":
students = students.OrderByDescending(s => s.EnrollmentDate);
break;
default:
students = students.OrderBy(s => s.FirstMidName);
break;
}

int pageSize = 2;

//ViewBag.TotalRecords = students.Count();  //因為PagedList.MVC中 IPagedList類型自帶的有集合總記錄數、每頁最大記錄數。 @Model.PageSize 指設置的是每頁最大記錄數。 @Model.TotalItemCount 總的最大記錄數,所以可以不使用ViewBag對象將最大記錄數和每頁最大記錄數返回視圖。

 

// ViewBag.recordPerpage = pageSize;

return View(students.ToPagedList(page,pageSize));
}

視圖代碼:

@model PagedList.IPagedList<ContosoUniversity.Models.Student>
@using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
@{
ViewBag.Title = "學生";
}

<h2>@ViewBag.Title</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>
@using (Html.BeginForm("Index", "Student", FormMethod.Get, new { @class="form-inline",role="form" }))
{
<label for="searchString" class="control-label">通過名字查找:</label> 
<div class="form-group">
@Html.TextBox("searchString", ViewBag.SearchString as string, htmlAttributes: new { @class = "form-control", placeholder = "請輸入名字" })   //只是在文本框中回顯當時查找的字符串,並沒 將 name為searchString的文本框表單提交
</div>

<input type="submit" value="查找" class="btn btn-primary" />
}
<table class="table table-hover table-striped">
<thead>
<tr>
<th>
@Html.ActionLink("名", "Index", new { sortOrder = ViewBag.LastNameSortParam, searchString = ViewBag.SearchString })
</th>
<th>
@Html.ActionLink("姓", "Index", new { sortOrder = ViewBag.FirstNameSortParam, searchString = ViewBag.SearchString })
</th>
<th>
@Html.ActionLink("入學時間", "Index", new { sortOrder = ViewBag.DateSortParam, searchString= ViewBag.SearchString })
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.FirstMidName)
</td>
<td>
@Html.DisplayFor(modelItem => item.EnrollmentDate)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
@Html.ActionLink("Details", "Details", new { id = item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.ID })
</td>
</tr>
}
</tbody>

<tfoot>
<tr>
<th class="text-info" colspan="5">
每頁 @Model.PageSize.ToString()  條記錄,共有 @Model.TotalItemCount.ToString() 條記錄。第 @(ViewBag.TotalRecords == 0 ? 0 : Model.PageNumber) 頁,共 @Model.PageCount 頁。   或者  

 每頁 @Model.PageSize 條記錄,共有 @Model.TotalItemCount 條記錄。第 @(Model.PageCount < Model.PageNumber ? 0 :Model.PageNumber) 頁,共 @Model.PageCount 頁。

這個條件表達式的目的是防止出現 記錄為0的情況,會出現 總頁數為0,而當前是第1頁的情況。

//PagedList.MVC中 IPagedList類型自帶的有分頁中用到的參數如:集合總記錄數、每頁最大記錄數。

@Model.PageSize 指設置的是每頁最大記錄數,

@Model.TotalItemCount 總的記錄數 ,

@Model.PageCount 總頁數,

 @Model.PageNumber 第幾頁,

@Model.Count() 當前頁面上包含的記錄數。


</th>
</tr>
</tfoot>


</table>
<br />


 //Page @(Model.PageCount< Model.PageNumber ? 0: Model.PageNumber)of @Model.PageCount

 

@Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, searchString = ViewBag.SearchString }))  

 

Html.PagedListPager(Model,Url,PagedListRenderOptions) 分頁輔助方法的  new PagedListRenderOptions() 參數可自定義顯示格式,可以

例如:

  @Html.PagedListPager(Model, page => Url.Action("Index", new { page }), new PagedListRenderOptions() { LinkToFirstPageFormat = "首頁", LinkToNextPageFormat = "下一頁", LinkToPreviousPageFormat = "上一頁", LinkToLastPageFormat = "末頁", DisplayItemSliceAndTotal = false, MaximumPageNumbersToDisplay = 3 })  

三、也可以 在視圖中使用參數來配置每頁顯示的條數。如果不使用Ajax異步提交的話,

視圖的表單上可以添加,size屬性用來設置顯示文本框的寬度,在Bootstrap樣式下同樣實用,另外,maxlength用來設置文本框接受字符的個數,輸多了輸不進去。

<label for="pageSize" class="control-label">每頁指定記錄數:</label>
<div class="form-group">
@Html.TextBox("pageSize", ViewBag.pageSize as string, htmlAttributes: new { @class = "form-control", size = "1", maxlength = "1" })
</div>

但是需要在排序,分頁中的 html中加入控制器返回的page參數值,page值由控制器返回ViewBag.page參數 

如:排序 @Html.ActionLink("評審項目類別", "Index", new { sortOrder = ViewBag.CategoryNameSortParam, searchString = ViewBag.searchString, categoryID = ViewBag.categoryID, isUsed = ViewBag.isUsed, pageSize = ViewBag.pageSize })

分頁:

<tfoot>
<tr>
<td class="text-muted" colspan="5">
每頁 @Model.PageSize 條記錄,共有 @Model.TotalItemCount 條記錄。第 @(Model.PageCount < Model.PageNumber ? 0 :Model.PageNumber) 頁,共 @Model.PageCount 頁。
</td>
</tr>
</tfoot>
</table>
@Html.PagedListPager(Model, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, searchString = ViewBag.searchString, categoryID = ViewBag.categoryID, isUsed = ViewBag.isUsed, pageSize = ViewBag.pageSize }),
new PagedListRenderOptions { LinkToFirstPageFormat = "首頁", LinkToNextPageFormat = "下一頁", LinkToPreviousPageFormat = "上一頁", LinkToLastPageFormat = "末頁", MaximumPageNumbersToDisplay = 3, DisplayItemSliceAndTotal = false }

 

控制器:

public ActionResult Index(string sortOrder,string searchString,string categoryID,bool? isUsed,int page=1,int pageSize =2 )
{
//設置每個頁面顯示記錄條數
ViewBag.pageSize = pageSize;

 

實現的全部效果如圖:

 

總結,排序、分頁程序從本質上講,就是視圖 調用控制器的操作方法,需要什么結果,就傳入什么參數。控件值要通過表單提交的方式傳入,排序通過鏈接實現。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM