再談使用X.PagedList.Mvc 分頁(ASP.NET Core 2.1)


在以前的博文中寫過使用X.PagedList.Mvc組件來對ASP.NET MVC應用程序進行分頁,可以參考此篇隨筆:Asp.net MVC 使用PagedList(新的已更名 為X.PagedList.Mvc) 分頁 

但是舊有的X.PagedList.MVC 依賴於.NET Framework版本,為了能夠支持ASP.NET Core MVC跨平台的實現,在ASP.NET Core MVC中無需再安裝.NET Framework,只需依賴於.NET Core。而且所有ASP.NET Core MVC的控制器 操作方法都默認是 異步方法,GitHub網址是:https://github.com/dncuug/X.PagedList

自己寫一個分頁並不麻煩,但功能肯定沒有 X.PagedList.Mvc.Core 強大。本文簡要介紹一下 X.PagedList.Mvc.Core 用於ASP.NET Core MVC的情況。

第一步:安裝 X.PagedList.Mvc.Core包,會自動安裝PagedList。有三種方式都可以完成安裝。

第1種、通過NuGet包獲取。在Visual Stuio 2017中,工具 --- NuGet包管理器 --- 管理解決方案中的NuGet程序包 ---瀏覽選項卡-- 在下面的搜索文本框中輸入  X.PagedList,或直接搜索 X.PagedList.Mvc.Core 

第2種:在NuGet程序包管理控制台安裝 ,輸入Install-package X.PagedList.Mvc.Core,自動安裝最新的版本的程序包和依賴(目前 為7.5.0),在解決方案管理器 中的依賴項,可以看到X.PagedList.Mvc.Core(7.5.0)程序包。

第3種:CLI命令行方式安裝:dotnet add package X.PagedList.Mvc.Core --version 7.5.0

當使用X.PagedList.Mvc.Core 7.60版本的時候,PagedListRenderOptions類定義在了 X.PagedList.Mvc.Core.Common命名空間下,因此在視圖需要改變默認的顯示樣式的時候,需要在視圖上引入X.PagedList.Mvc.Core.Common命名空間。

第二步:使用X.PagedList.Mvc.Core.還是以微軟ASP.NET MVC Core官方的例子。微軟官方教程里面分頁沒有用到X.PagedList.Mvc.Core,而是自定義一個簡單的分頁類。

在控制器中,在IEnumerable/IQueryable對象調用 方法   .ToPagedList(page,pageSize)或..ToPagedListAsync(page,pageSize))將IEnumerable/IQueryable對象轉換成IPagedList對象返加給視圖。

在視圖中,可以使用 

1、@Html.PagedListPager(IPagedList list,Fun<int,string>GeneratePageUrl) 第一個參數為控制器返回的IpagedList對象,第二個參數是創建分頁的URL。

2、或 @Htm.PagedListPager(IPagedList list,Fun<int,string>GeneratePageUrl,PagedListRenderOptions options) 此方法多了一個參數 PagedListRenderOptions,可以定義顯示的格式。

在X.PagedList.Mvc.Core,IpagedList類型自帶的返回給視圖的分頁參數有:

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

@Model.TotalItemCount 總的記錄數 ,

@Model.PageCount 總頁數,

 @Model.PageNumber 第幾頁,

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

 

控制器代碼:

@using X.PagedList; //引入命名空間

// GET: Students

public async Task<IActionResult> Index(string sortOrder,string searchString,int page =1,int pageSize=5) //默認每頁最多顯示5行記錄
{

ViewData["CurrentSort"] = sortOrder;

ViewData["NameSortParm"] = string.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewData["DateSortParm"] = sortOrder == "date" ? "date_desc" : "date";

var students = from s in _context.Students
select s;
if (!string.IsNullOrEmpty(searchString))
{
students = students.Where(s => s.LastName.Contains(searchString) || s.FirstMidName.Contains(searchString));

}
ViewData["SearchString"] = searchString;

switch (sortOrder)
{
case "name_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.LastName);
break;
}

ViewData["PageSize"] = pageSize; //每頁最多顯示的記錄數的返回給視圖。以便在下次查詢和排序的時候,每頁也顯示相同的記錄數。

return View(await students.AsNoTracking().ToPagedListAsync(page,pageSize)); //執行異步方法;

}

 

視圖:

@model X.PagedList.IPagedList<ContosoUniversity.Models.Student>
@using X.PagedList.Mvc.Core;

@X.PagedList.Mvc.Core.Common;  //@using X.PagedList.Mvc.Core.Common;  7.6及以上版本需要引入Common命名空間,以支持PagedListRenderOptions .7.5以下的版本則不需要。


@{
ViewData["Title"] = "Index";
}

<link rel="stylesheet" href="~/css/PagedList.css" /> //將PagedList.css拷入程序css文件下,以便顯示出支持Bootstrap4支格式的輸出。

<h2>Index</h2>

<p>
<a asp-action="Create">Create New</a>
</p>

<form asp-action="Index" method="get" class="form-inline" role="form">
<label for="pageSize" class="control-label">每頁指定記錄數:</label>
<div class="form-group">
<input type="number" name="pageSize" id="pageSize" value="@ViewData["PageSize"]" class="form-control" size="1" maxlength="4" min="1" max="1000" />    //使用<input type="number">能保證輸入的始終為數字,字符輸不進去,但size和maxlength卻失效了。text能保證文本框的寬度和能接受的字符數。  在<input type="number"  min ="1" max="100">中,max決定了文本框的寬度。

@ 在<inputy type="text*>中, size屬性用來設置顯示文本框的寬度,在Bootstrap樣式下同樣實用,另外,maxlength用來設置文本框接受字符的個數,輸多了輸不進去。*@
</div>
<text>&nbsp;&nbsp;</text>
<label for="searchString" class="control-label">片名:</label>
<div class="form-group">
@Html.TextBox("searchString", ViewData["SearchString"] as string, htmlAttributes: new { @class = "form-control", placeHolder = "請輸入片名" })
</div>
<text>&nbsp;&nbsp;</text>
<input type="submit" value="Search" class="btn btn-primary" />
<a asp-action="Index">Back to Full List</a>
</p>

</form>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>
<a asp-action="Index" asp-route-sortOrder="@ViewData["NameSortParm"]" asp-route-searchString="@ViewData["SearchString"]" asp-route-pageSize="@ViewData["PageSize"]">LastName</a> //感覺TagHelper 還沒有HtmlHelper在這里好用。
</th>
<th>
FirstMidName
</th>
<th>
<a asp-action="Index" asp-route-sortOrder="@ViewData["DateSortParm"]" asp-route-searchString="@ViewData["SearchString"]" asp-route-pageSize="@ViewData["PageSize"]">EnrollmentDate</a>
</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>
<a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-action="Details" asp-route-id="@item.ID">Details</a> |
<a asp-action="Delete" asp-route-id="@item.ID">Delete</a>

</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td class="text-muted" colspan="4">
每頁 @Model.PageSize 條記錄,本頁有 @Model.Count 條記錄,共有 @Model.TotalItemCount 條記錄。第 @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) 頁,共 @Model.PageCount 頁。
@*這個條件表達式的目的是防止出現 記錄為0的情況,會出現 總頁數為0,而當前是第1頁的情況。*@
</td>
</tr>
</tfoot>
</table>

@Html.PagedListPager(Model,page =>Url.Action("Index",new { page,sortOrder = ViewData["CurrentSort"], searchString = ViewData["SearchString"],pageSize=ViewData["PageSize"] }), new PagedListRenderOptions { LinkToFirstPageFormat = "首頁", LinkToNextPageFormat = "下一頁", LinkToPreviousPageFormat = "上一頁", LinkToLastPageFormat = "末頁", MaximumPageNumbersToDisplay = 5, DisplayItemSliceAndTotal = false })

 

 

Asp.NET Razor Pages 補充說明:

在RazorPages 中,不能使用 @Html.PagedListPager(Model.Students, page => Url.Action("Index", new { page}))  參數名稱不能指定 為page, 如指定page,將不能正確創建 分頁的鏈接。可能的原因是 page在Razor頁面框架下有特定的含義,與之沖突。

1、可將參數page修改為pageIndex,@Html.PagedListPager(Model.Students, pageIndex => Url.Action("Index", new { pageIndex}))   //在Razor Pages 中,URL.Action()也可以使用 URL.Page()來代替。

2、PageModel類也要作修改:

 public async Task OnGetAsync(string sortOrder,string searchString,int pageIndex =1,int pageSize=3)

 

關於支持Bootstrap版本的問題:

目前的PagedList.Mvc.Corer 版本默認支持Bootstrap3,而最新的基架創建的引用的是 Bootstrap4,    new PagedListRenderOptions 不能渲染分頁按鈕的樣式。因此,需要 指定 ul li 的樣式。

Bootstrap 4 使用無序列表進行分頁,樣式為:

<ul class="pagination">

   <li class="page-item"> <a class="page-link" href="#">Previous</a></li>

   <li class="page-item"><a class="page-link" href="#">1</a></li>

   <li class="page-item"><a class="page-link" href="#">2</a></li>

   <li class="page-item"><a class="page-link" href="#">3</a></li>

   <li class="page-item"><a class="page-link" href="#">Next</a></li>

</ul>

 

@Html.PagedListPager(Model.Students, page => Url.Action("Index", new { page, sortOrder = Model.CurrentSort, searchString = Model.CurrentFilter, pageSize = Model.PageSize }),
new PagedListRenderOptions
{
LinkToFirstPageFormat = "首頁",
LinkToNextPageFormat = "下一頁",
LinkToPreviousPageFormat = "上一頁",
LinkToLastPageFormat = "末頁",
MaximumPageNumbersToDisplay = 5,
DisplayItemSliceAndTotal = false,//從頭到尾顯示頁碼

 

 UlElementClasses = new[] { "pagination"},  // 為ul li a 元素添加鏈接,使用ContainerDivClasses = new[] { "pagination" }替換 UlElementClasses = new[] { "pagination"},也是相同的效果。也可以不要此行代碼,因為Bootstrap4與3相比,ul的class名沒有變化,li 元素和a 元素加了page-item和page-link的類名。

LiElementClasses = new[] { "page-item" },
PageClasses = new[] { "page-link" },

})

 

 

 可以使用X.PagedList.Mvc.Bootstrap4 包來替換X.PagedList.Mvc.Core。

Install-Package X.PagedList.Mvc.Bootstrap4

index.cshtml文件中的引用,

@using X.PagedList.Mvc.Core;   //用以支持Html.PagedListPager方法
@using X.PagedList.Mvc.Bootstrap4.NetCore; // 用以支持 Bootstrap4PagedListRenderOptions ,能渲染成bootstrap4

@Html.PagedListPager(Model.Students, pageIndex => Url.Action("Index", new { pageIndex, sortOrder = Model.CurrentSort, searchString = Model.CurrentFilter, pageSize = Model.PageSize }),
Bootstrap4PagedListRenderOptions.ClassicPlusFirstAndLast)


免責聲明!

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



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