Fala galera,
Hoje irei mostrar como fazer uma paginação em uma tabela no MVC, pois é tem que ser feita na mão adeus ao GridView.
Bom vamos la.
Obs: Neste exemplo estou usando Entity Framework, no final usarei um objeto do EF, se usar outro tipo de persistencia somente altere o objeto para uma lista do seu objeto (List<SeuObj>).
Primeiro vamos modificar o global.asax, incluindo uma nova rota.
Dentro do método RegisterRoutes, deixando ele assim:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Paginacao", // Route name
"{controller}/{page}", // URL with parameters
new { action = "Index" } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
Certo ele auxiliara mais a frente quando chamarmos o link da paginação.
Proximo passo é criar a classe de paginação, ficará assim:
public class PaginatedList<T> : List<T>
{
public int PageIndex { get; private set; }
public int PageSize { get; private set; }
public int TotalCount { get; private set; }
public int TotalPages { get; private set; }
public string Controller { get; private set; }
public string Action { get; private set; }
public PaginatedList(IEnumerable<T> source, int pageIndex, int pageSize, string controller)
{
Add(source, pageIndex, pageSize, controller, string.Empty);
}
public PaginatedList(IEnumerable<T> source, int pageIndex, int pageSize, string controller, string action)
{
Add(source, pageIndex, pageSize, controller, action);
}
void Add(IEnumerable<T> source, int pageIndex, int pageSize, string controller, string action)
{
PageIndex = pageIndex;
PageSize = pageSize;
TotalCount = source.Count();
TotalPages = (int)Math.Ceiling(TotalCount / (double)PageSize);
Controller = controller;
Action = action;
this.AddRange(source.Skip(PageIndex * PageSize).Take(PageSize));
}
public bool HasPreviousPage
{
get
{
return (PageIndex > 0);
}
}
public bool HasNextPage
{
get
{
return (PageIndex + 1 < TotalPages);
}
}
public void Paginacao()
{
HttpResponse response = HttpContext.Current.Response;
if (string.IsNullOrEmpty(Action))
{
if (HasPreviousPage)
response.Write(string.Format("<a href='/{0}/{1}'>{2}</a>", Controller, PageIndex - 1, "<<<"));
if (HasNextPage)
response.Write(string.Format("<a href='/{0}/{1}'>{2}</a>", Controller, PageIndex + 1, ">>>"));
}
else
{
if (HasPreviousPage)
response.Write(string.Format("<a href='/{0}/{1}/{2}'>{3}</a>", Controller, Action, PageIndex - 1, "<<<"));
if (HasNextPage)
response.Write(string.Format("<a href='/{0}/{1}/{2}'>{3}</a>", Controller, Action, PageIndex + 1, ">>>"));
}
}
}
Após criar essa classe ja temos um novo retorno de Model para nossa view.
Em nossa aspx, no caso estou utilizando a index.aspx para listar as informações devemos mudar o inherits da pagina da seguinte forma.
Inherits="System.Web.Mvc.ViewPage<HelloMVC.MVC.Controllers.PaginatedList<HelloMVC.MVC.Models.TB_Usuario>>"
Reparem que na ViewPage ao invez de eu passar como generics type IEnumerable, estou passando nossa classe PaginatedList, lembrando que deve passar corretamente o caminho senao temos o seguinte erro:
Após a modificação deverá funcionar a página, com tudo funcionando iremos atribuir a paginação na página.
Então vamos ao nosso aspx novamente e iremos chamar um método que está na nossa classe de paginação, devendo ficar assim:
</table>
<% Model.Paginacao(); %>
Eu coloquei abaixo da table, porém fica ao seu critério.
Enfim vamos ao nosso controller da página
No método Index iremos fazer uma pequena modificação:
public ActionResult Index(int? page)
{
ViewData.Model = new PaginatedList<TB_Usuario>(usu, page ?? 0, 2, "Usuario");
return View();
}
Essa modificação devemos passar o objeto que retornará na lista por parâmetro genérico <TB_Usuario> e a lista db.TB_Usuario como primeiro parâmetro.
O terceiro parâmetro é o controller usado.
Podendo também incluir um parâmetro a mais para passar o action, se utilizarmo esse contrutor com action temos que criar uma nova rota no global.asax
Com tudos parâmetros sendo atribuidos corretamente é só rodar o projeto e sua paginação estará funcionando.
Até o proximo.