Qual é a maneira mais preferida e fácil de fazer a paginação na ASP.NET MVC? Ou seja, qual é a maneira mais fácil de dividir uma lista em várias páginas navegáveis.
Como exemplo, digamos que recebo uma lista de elementos de um banco de dados / gateway / repositório como este:
public ActionResult ListMyItems()
{
List<Item> list = ItemDB.GetListOfItems();
ViewData["ItemList"] = list;
return View();
}
Para simplificar, gostaria de especificar apenas um número de página para minha ação como parâmetro. Como isso:
public ActionResult ListMyItems(int page)
{
//...
}
fonte
ActionLink
sintaxe está me dando um erro de compilação ao solicitar a página. CS0103: O nome 'startIndex' não existe no contexto atual. Esta técnica não é possível com MVC2?startIndex
e adicionassepageSize
a ela. Eu esperava que fosse usar automaticamente os valores da última chamada paraSearch
. Como eu usaria ostartIndex
from the lastSearch
no meuActionLink
?Eu tive o mesmo problema e encontrei uma solução muito elegante para uma classe Pager de
http://blogs.taiga.nl/martijn/2008/08/27/paging-with-aspnet-mvc/
Em seu controlador, a chamada se parece com:
return View(partnerList.ToPagedList(currentPageIndex, pageSize));
e na sua opinião:
<div class="pager"> Seite: <%= Html.Pager(ViewData.Model.PageSize, ViewData.Model.PageNumber, ViewData.Model.TotalItemCount)%> </div>
fonte
Eu queria abordar uma maneira simples de fazer isso com o front end também:
Controlador:
public ActionResult Index(int page = 0) { const int PageSize = 3; // you can always do something more elegant to set this var count = this.dataSource.Count(); var data = this.dataSource.Skip(page * PageSize).Take(PageSize).ToList(); this.ViewBag.MaxPage = (count / PageSize) - (count % PageSize == 0 ? 1 : 0); this.ViewBag.Page = page; return this.View(data); }
Visão:
@* rest of file with view *@ @if (ViewBag.Page > 0) { <a href="@Url.Action("Index", new { page = ViewBag.Page - 1 })" class="btn btn-default"> « Prev </a> } @if (ViewBag.Page < ViewBag.MaxPage) { <a href="@Url.Action("Index", new { page = ViewBag.Page + 1 })" class="btn btn-default"> Next » </a> }
fonte
var data = this.dataSource.Skip(page * PageSize).Take(PageSize).ToList();
Requer umorderBy(o => o.Id)
antes de usarskip()
|| Além disso, esta é uma ótima resposta que merece muito mais votos positivos.Aqui está um link que me ajudou com isso.
Ele usa o pacote PagedList.MVC NuGet. Vou tentar resumir as etapas
Instale o pacote PagedList.MVC NuGet
Construir projeto
Adicionar
using PagedList;
ao controladorModifique sua ação para definir a página
public ActionResult ListMyItems(int? page) { List list = ItemDB.GetListOfItems(); int pageSize = 3; int pageNumber = (page ?? 1); return View(list.ToPagedList(pageNumber, pageSize)); }
Adicione links de paginação na parte inferior de sua visualização
@*Your existing view*@ 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 }))
fonte
Controlador
[HttpGet] public async Task<ActionResult> Index(int page =1) { if (page < 0 || page ==0 ) { page = 1; } int pageSize = 5; int totalPage = 0; int totalRecord = 0; BusinessLayer bll = new BusinessLayer(); MatchModel matchmodel = new MatchModel(); matchmodel.GetMatchList = bll.GetMatchCore(page, pageSize, out totalRecord, out totalPage); ViewBag.dbCount = totalPage; return View(matchmodel); }
Logíca de negócios
public List<Match> GetMatchCore(int page, int pageSize, out int totalRecord, out int totalPage) { SignalRDataContext db = new SignalRDataContext(); var query = new List<Match>(); totalRecord = db.Matches.Count(); totalPage = (totalRecord / pageSize) + ((totalRecord % pageSize) > 0 ? 1 : 0); query = db.Matches.OrderBy(a => a.QuestionID).Skip(((page - 1) * pageSize)).Take(pageSize).ToList(); return query; }
Exibir para exibir a contagem total de páginas
if (ViewBag.dbCount != null) { for (int i = 1; i <= ViewBag.dbCount; i++) { <ul class="pagination"> <li>@Html.ActionLink(@i.ToString(), "Index", "Grid", new { page = @i },null)</li> </ul> } }
fonte
Acho que a maneira mais fácil de criar paginação no aplicativo ASP.NET MVC é usando a biblioteca PagedList.
Há um exemplo completo no seguinte repositório github. Espero que ajude.
public class ProductController : Controller { public object Index(int? page) { var list = ItemDB.GetListOfItems(); var pageNumber = page ?? 1; var onePageOfItem = list.ToPagedList(pageNumber, 25); // will only contain 25 items max because of the pageSize ViewBag.onePageOfItem = onePageOfProducts; return View(); } }
Link de demonstração: http://ajaxpagination.azurewebsites.net/
Código-fonte: https://github.com/ungleng/SimpleAjaxPagedListAndSearchMVC5
fonte
Entidade
public class PageEntity { public int Page { get; set; } public string Class { get; set; } } public class Pagination { public List<PageEntity> Pages { get; set; } public int Next { get; set; } public int Previous { get; set; } public string NextClass { get; set; } public string PreviousClass { get; set; } public bool Display { get; set; } public string Query { get; set; } }
HTML
<nav> <div class="navigation" style="text-align: center"> <ul class="pagination"> <li class="page-item @Model.NextClass"><a class="page-link" href="?page=@(@[email protected])">«</a></li> @foreach (var item in @Model.Pages) { <li class="page-item @item.Class"><a class="page-link" href="?page=@([email protected])">@item.Page</a></li> } <li class="page-item @Model.NextClass"><a class="page-link" href="?page=@(@[email protected])">»</a></li> </ul> </div> </nav>
Paging Logic
public Pagination GetCategoryPaging(int currentPage, int recordCount, string query) { string pageClass = string.Empty; int pageSize = 10, innerCount = 5; Pagination pagination = new Pagination(); pagination.Pages = new List<PageEntity>(); pagination.Next = currentPage + 1; pagination.Previous = ((currentPage - 1) > 0) ? (currentPage - 1) : 1; pagination.Query = query; int totalPages = ((int)recordCount % pageSize) == 0 ? (int)recordCount / pageSize : (int)recordCount / pageSize + 1; int loopStart = 1, loopCount = 1; if ((currentPage - 2) > 0) { loopStart = (currentPage - 2); } for (int i = loopStart; i <= totalPages; i++) { pagination.Pages.Add(new PageEntity { Page = i, Class = string.Empty }); if (loopCount == innerCount) { break; } loopCount++; } if (totalPages <= innerCount) { pagination.PreviousClass = "disabled"; } foreach (var item in pagination.Pages.Where(x => x.Page == currentPage)) { item.Class = "active"; } if (pagination.Pages.Count() <= 1) { pagination.Display = false; } return pagination; }
Usando o controlador
public ActionResult GetPages() { int currentPage = 1; string search = string.Empty; if (!string.IsNullOrEmpty(Request.QueryString["page"])) { currentPage = Convert.ToInt32(Request.QueryString["page"]); } if (!string.IsNullOrEmpty(Request.QueryString["q"])) { search = "&q=" + Request.QueryString["q"]; } /* to be Fetched from database using count */ int recordCount = 100; Place place = new Place(); Pagination pagination = place.GetCategoryPaging(currentPage, recordCount, search); return PartialView("Controls/_Pagination", pagination); }
fonte
public ActionResult Paging(int? pageno,bool? fwd,bool? bwd) { if(pageno!=null) { Session["currentpage"] = pageno; } using (HatronEntities DB = new HatronEntities()) { if(fwd!=null && (bool)fwd) { pageno = Convert.ToInt32(Session["currentpage"]) + 1; Session["currentpage"] = pageno; } if (bwd != null && (bool)bwd) { pageno = Convert.ToInt32(Session["currentpage"]) - 1; Session["currentpage"] = pageno; } if (pageno==null) { pageno = 1; } if(pageno<0) { pageno = 1; } int total = DB.EmployeePromotion(0, 0, 0).Count(); int totalPage = (int)Math.Ceiling((double)total / 20); ViewBag.pages = totalPage; if (pageno > totalPage) { pageno = totalPage; } return View (DB.EmployeePromotion(0,0,0).Skip(GetSkip((int)pageno,20)).Take(20).ToList()); } } private static int GetSkip(int pageIndex, int take) { return (pageIndex - 1) * take; } @model IEnumerable<EmployeePromotion_Result> @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Paging</title> </head> <body> <div> <table border="1"> @foreach (var itm in Model) { <tr> <td>@itm.District</td> <td>@itm.employee</td> <td>@itm.PromotionTo</td> </tr> } </table> <a href="@Url.Action("Paging", "Home",new { pageno=1 })">First page</a> <a href="@Url.Action("Paging", "Home", new { bwd =true })"><<</a> @for(int itmp =1; itmp< Convert.ToInt32(ViewBag.pages)+1;itmp++) { <a href="@Url.Action("Paging", "Home",new { pageno=itmp })">@itmp.ToString()</a> } <a href="@Url.Action("Paging", "Home", new { fwd = true })">>></a> <a href="@Url.Action("Paging", "Home", new { pageno = Convert.ToInt32(ViewBag.pages) })">Last page</a> </div> </body> </html>
fonte