Постраничный список не работает

Я сделал учебник «Начало работы с ASP.NET MVC 3 (C#)» Рика Андерсона, это каталог продуктов, который уже работает, но, поскольку я добавил длинный список продуктов, теперь мне нужен pagedList, чтобы получить только число продуктов на страницу, осмотревшись, я нашел пример, но не работает, в свой проект я добавил в файл моделей этот класс с именем IPagedList.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Presupuestos.Models
{
    public interface IPagedList
    {
        int ItemCount
        {
            get;
            set;
        }

        int PageCount
        {
            get;
            set;
        }

        int PageIndex
        {
            get;
            set;
        }

        int PageSize
        {
            get;
            set;
        }

        bool IsPreviousPage
        {
            get;
        }

        bool IsNextPage
        {
            get;
        }
    }

    public interface IPagedList<T> : IList<T>, IPagedList
    {
    }

    public class PagedList<T> : List<T>, IPagedList<T>
    {
        private List<Productos> list;
        private int p;
        private int p_2;

        public PagedList(IQueryable<T> source, int index, int pageSize)
        {
            this.ItemCount = source.Count();
            this.PageSize = pageSize;
            this.PageIndex = index;
            this.AddRange(source.Skip(index * pageSize).Take(pageSize).ToList());
            this.PageCount = (int)Math.Ceiling((double)this.ItemCount / this.PageSize);
        }

        public PagedList(List<T> source, int index, int pageSize)
        {
            this.ItemCount = source.Count();
            this.PageSize = pageSize;
            this.PageIndex = index;
            this.AddRange(source.Skip(index * pageSize).Take(pageSize).ToList());
        }

        public PagedList(List<Productos> list, int p, int p_2)
        {
            // TODO: Complete member initialization
            this.list = list;
            this.p = p;
            this.p_2 = p_2;
        }

        public int ItemCount
        {
            get;
            set;
        }

        public int PageCount
        {
            get;
            set;
        }

        public int PageIndex
        {
            get;
            set;
        }

        public int PageSize
        {
            get;
            set;
        }

        public bool IsPreviousPage
        {
            get
            {
                return (PageIndex > 0);
            }
        }

        public bool IsNextPage
        {
            get
            {
                return (PageIndex + 1) * PageSize <= ItemCount;
            }
        }
    }

    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);
        }
    }
}

Кроме того, я добавил еще один класс с именем HTMLHelpers.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Text;
using Presupuestos.Models;

namespace Presupuestos.Models
{
    public static class ListPaging
    {
        public static MvcHtmlString Paging(this HtmlHelper html, IPagedList pagedList, string url, string pagePlaceHolder)
        {
            StringBuilder sb = new StringBuilder();
            // only show paging if we have more items than the page size
            if (pagedList.ItemCount > pagedList.PageSize)
            {
                sb.Append("<ul class=\"paging\">");
                if (pagedList.IsPreviousPage && pagedList.PageIndex != 1)
                {
                    // previous link
                    sb.Append("<li class=\"prev\"><a href=\"");
                    sb.Append(url.Replace(pagePlaceHolder, (pagedList.PageIndex - 1).ToString()));
                    sb.Append("\" title=\"Go to Previous Page\">prev</a></li>");
                }
                for (int i = 0; i < pagedList.PageCount; i++)
                {
                    sb.Append("<li>");
                    if (i == pagedList.PageIndex)
                    {
                        sb.Append("<span>").Append((i + 1).ToString()).Append("</span>");
                    }
                    else
                    {
                        sb.Append("<a href=\"");
                        sb.Append(url.Replace(pagePlaceHolder, (i + 1).ToString()));
                        sb.Append("\" title=\"Go to Page ").Append((i + 1).ToString());
                        sb.Append("\">").Append((i + 1).ToString()).Append("</a>");
                    }
                    sb.Append("</li>");
                }
                if (pagedList.IsNextPage)
                {
                    // next link
                    sb.Append("<li class=\"next\"><a href=\"");
                    sb.Append(url.Replace(pagePlaceHolder, (pagedList.PageIndex + 1).ToString()));
                    sb.Append("\" title=\"Go to Next Page\">next</a></li>");
                }
                sb.Append("</ul>");
            }
            return MvcHtmlString.Create(sb.ToString());
        }
    }
}

Наконец, это файл представления, я только что добавил @using presupuestos.models и последний html.paging в конце:

@model IEnumerable<Presupuestos.Models.Productos>        
@using Presupuestos.Models

@{
    ViewBag.Title = "Productos";
}

<h2>Catalogo de Productos</h2>

<p>
    @Html.ActionLink("Agregar Producto", "Create")
</p>
<table>
    <tr>
        <th>
            Marca
        </th>
        <th>
            Codigo
        </th>
        <th>
            Nombre
        </th>
        <th>
            Envase
        </th>
        <th>
            Presentación
        </th>
        <th>
            Linea
        </th>
        <th>
            Categoria
        </th>
        <th></th>
    </tr>

@foreach (var item in Model)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.marca)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.codigo)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.nombre)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.envase)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.presentación)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.linea)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.categoria)
        </td>
        <td>
            @Html.ActionLink("Editar", "Edit", new { id = item.ID }) |
            @Html.ActionLink("Detalles", "Details", new { id = item.ID }) |
            @Html.ActionLink("Borrar", "Delete", new { id = item.ID })
        </td>
    </tr>
}

</table>
<div>
@Html.Paging(new PagedList<Productos>(ViewData.Model.ToList(),1,10), Url.Action("Index","Index", new { page = "PAGENUM" }), "PAGENUM")
</div>

Надеюсь, вы можете мне помочь, я застрял с этим на один день, только в прошлую пятницу я начал использовать mvc3, хорошо, что моему боссу нужно то, что есть в учебнике, но теперь, когда я хотел сделать это дополнительно (список страниц) я действительно потерялся!!


person Ivelisse    schedule 17.07.2012    source источник
comment
Пожалуйста, не могли бы вы сказать немного конкретнее, что не работает.   -  person ngm    schedule 18.07.2012
comment
А также было бы полезно, если бы вы могли опубликовать, откуда взят пример IPagedList.   -  person ngm    schedule 18.07.2012
comment
Я отлаживаю и запускаю, и я вижу список со всеми сохраненными записями в базе данных, но список страниц не работает, не отображается внизу страницы, я получил код отсюда forums.asp.net/t/1678594.aspx/1/10 с исправлениями, внесенными некоторыми авторы поста   -  person Ivelisse    schedule 18.07.2012
comment
Вы пытаетесь создать свой собственный список страниц? почему бы вам не попробовать github.com/TroyGoode/PagedList?   -  person VJAI    schedule 18.07.2012
comment
Я пытался сделать этот пример раньше, но я не мог этого сделать :(   -  person Ivelisse    schedule 18.07.2012


Ответы (2)


Как будто в этой строке

@Html.Paging(new PagedList<Productos>(ViewData.Model.ToList(),1,10), Url.Action("Index","Index", new { page = "PAGENUM" }), "PAGENUM")

вы жестко кодируете текущий индекс страницы равным 1.

Я предполагаю, что в вашем методе действия Index вам может понадобиться что-то, представляющее вашу текущую страницу, которую вы можете передать в свое представление, и заменить жестко запрограммированную 1 на это.

e.g.

public void Index(int page = 1)
{
    // ... set up your view model
    // ...
    // ...

    // page is added to the url by your paging helper.
    ViewBag.CurrentPage = page;

    return View(viewModel);
}

А в представлении...

@Html.Paging(new PagedList<Productos>(ViewData.Model.ToList(),@ViewBag.CurrentPage,10), Url.Action("Index","Index", new { page = "PAGENUM" }), "PAGENUM")
person ngm    schedule 17.07.2012
comment
Я отредактировал изменение, чтобы оно выглядело так public ViewResult Index(int page = 1) { ViewBag.CurrentPage = page; return View(db.Productos.ToList()); }, и вставил то, что вы написали, в представлении, но все равно ничего не происходит. - person Ivelisse; 18.07.2012

Основываясь на том, что вы сказали в своем комментарии, что постраничный список не отображается внизу страницы, я действительно рекомендую выполнить некоторую отладку и посмотреть, какие пути кода действительно выполняются. Но в любом случае мы можем предположить следующее...

Первый шаг — поставить точку останова в ListPaging.Paging и проверить, действительно ли она вызывается. Если это так, и к вашему StringBuilder вообще ничего не добавляется, то, возможно,

if (pagedList.ItemCount > pagedList.PageSize)
{
     // ...

не оценивается как истина. Я предполагаю, что в вашем списке больше элементов, чем 10, так что это должно быть правдой. Так что, возможно, причина, по которой это не оценивается как true, заключается в том, что ни одно значение не установлено.

Добавленный вами конструктор выглядит сомнительно:

public PagedList(List<Productos> list, int p, int p_2)
{
    // TODO: Complete member initialization
    this.list = list;
    this.p = p;
    this.p_2 = p_2;
}

Ни одно из свойств, которые использует PagedList, на самом деле не устанавливается здесь. какой смысл в этом конструкторе? Что такое p и p_2? Если этот конструктор вызывается, то ItemCount и PageSize не будут иметь значения. Я бы предложил избавиться от него и разрешить вызывать другие конструкторы.

person ngm    schedule 18.07.2012
comment
Да! я избавился от этого, я ищу новый способ сделать это, спасибо! - person Ivelisse; 18.07.2012