01 April 2008 ASP.NET MVC, Paging Robert Muehsig

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:

image

Ähnlich wie bei den oben genannten Seite hab ich auch ein Paging implementiert:

image

image

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


Written by Robert Muehsig

Software Developer - from Dresden, Germany, now living & working in Switzerland. Microsoft MVP & Web Geek.
Other Projects: KnowYourStack.com | ExpensiveMeeting | EinKofferVollerReisen.de

If you like the content and want to support me you could buy me a beer or a coffee via Litecoin or Bitcoin - thanks for reading!