In meinem kleinen Testprojekt (was ich auch demnächst hier veröffentlichen werde) baue ich eine Art DotNetKicks bzw. Digg Klon. Sowas gibts zwar schon und nennt sich "Kigg", aber ich hab damit noch etwas mehr vor und wollte mich einarbeiten :)
Momentaner Stand sieht (auf der Startseite) so aus:
Ähnlich wie bei den oben genannten Seite hab ich auch ein Paging implementiert:
Zuerst hab ich die Lösung von Rob Conery gefunden.
Allerdings fing dort das zählen bei 0 an - und eine Seite 0 hat mir nicht wirklich gefallen, daher hab ich diese Klasse etwas erweitert und noch eine TotalPages Property hinzugefügt:
public class PagedList<T> : List<T> { public PagedList(IQueryable<T> source, int index, int pageSize) { this.TotalCount = source.Count(); this.PageSize = pageSize; this.PageIndex = index; this.AddRange(source.Skip((index - 1) * pageSize).Take(pageSize).ToList()); int pageResult = 0; for (int counter = 1; pageResult < this.TotalCount; counter++) { pageResult = counter * this.PageSize; this.TotalPages = counter; } } public int TotalPages { get; set; } public int TotalCount { get; set; } public int PageIndex { get; set; } public int PageSize { get; set; } public bool HasPreviousPage { get { return (PageIndex > 1); } } public bool HasNextPage { get { return (PageIndex * PageSize) <= TotalCount; } } } public static class Pagination { public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index, int pageSize) { return new PagedList<T>(source, index, pageSize); } public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index) { return new PagedList<T>(source, index, 10); } }
Für das letztliche Design hab ich die CSS von diesem Blogpost hier genommen.
In meinem List View sieht das am Ende dann so aus (was mich etwas an meine PHP Zeiten erinnert) :
<ul class="pagination-clean"> <% if (ViewData.EntryList.HasPreviousPage) { %> <li class="previous"><%=Html.ActionLink<Mvc2.Controllers.EntryController>(c => c.List(ViewData.Category, ViewData.EntryList.PageIndex - 1), "« Previous")%></li> <% } else { %> <li class="previous-off">« Previous</li> <% } %> <%for (int page = 1; page <= ViewData.EntryList.TotalPages; page++) { if (page == ViewData.EntryList.PageIndex) { %> <li class="active"><%=page.ToString()%></li> <%} else { %> <li><%=Html.ActionLink<Mvc2.Controllers.EntryController>(c => c.List(ViewData.Category, page), page.ToString())%></li> <%} } if (ViewData.EntryList.HasNextPage) { %> <li class="next"><%=Html.ActionLink<Mvc2.Controllers.EntryController>(c => c.List(ViewData.Category, ViewData.EntryList.PageIndex + 1), "Next »")%></li> <% } else { %> <li class="next-off">Next »</li> <% } %> </ul>
In ViewData.EntryList steckt am Ende nur die PageList. Meinem EntryContoller (bzw. dessen "List" Methode) übergeb ich die momentan angewählte Kategorie und die Seite.
Resultat ist am Ende ein funktionierendes Paging, mit solchen URLs: http://localhost:56891/Entry/List/All/3 für Seite 3 bei allen Kategorien.
Den kompletten Source Code werde ich später noch nachreichen - zusammen mit dem gesamten MVC Testprojekt