À L'Aide De @Html.DisplayNameFor () avec PagedList

j'ai essayé le paquet PagedList pour obtenir une pagination pour mes vues index. Tout se passait bien, et au niveau du contrôleur tout fonctionne bien, il n'affiche que 5 enregistrements par page, et affiche la page appropriée basée sur le querystring.

Mon problème est dans la vue. J'ai changé le @Modèle PagedList.IPagedList pour que je puisse accéder au Model.HasNextPage et d'autres propriétés, mais maintenant, le @Html.DisplayNameFor(model => model.ItemName) ne fonctionnent plus. Je reçois ce erreur:

PagedList.IPagedList<Dossier.Models.Item>' does not contain a definition for 'ItemName' and no extension method 'ItemName' accepting a first argument of type 'PagedList.IPagedList<Dossier.Models.Item>' could be found (are you missing a using directive or an assembly reference?)

Voici les parties pertinentes de la vue:

@model PagedList.IPagedList<Dossier.Models.Item>
@using Dossier.Models.Item

...

<th>
    @Html.DisplayNameFor(model => model.ItemName)
</th>

il semble que IPagedList n'est pas compatible avec DisplayNameFor(). Une idée de pourquoi ça arrive, et comment je peux arranger ça? Je sais que je pourrais juste entrer manuellement les noms de colonne, mais je tiens à rester (et modifiable) dans le modèle plus tard.

42
demandé sur nb_ 2013-02-18 08:04:16

4 réponses

Vous pouvez essayer ce

@Html.DisplayNameFor(model => model.FirstOrDefault().ItemName)
74
répondu ViniciusdeLemos 2016-05-25 06:55:22

comme solution alternative à la réponse acceptée, rappelez-vous que IPagedList hérite de IEnumerable. Cela signifie que vous pourriez écrire:

@model IEnumerable<Dossier.Models.Item>

au début de la page, et il suffit de lancer le modèle sur IPagedList si nécessaire:

@Html.PagedListPager((IPagedList)Model, page => Url.Action("Index", new { page = page }))

Vous pouvez même déclarer l'coulé variable dans l'en-tête, afin de l'utiliser plusieurs fois dans la page:

@{
    ViewBag.Title = "My page title";
    var pagedlist = (IPagedList)Model;
}

cela vous permettrait d'utiliser la méthode DisplayNameFor helper, et d'accéder à toutes les PagedList méthodes / propriétés, sans avoir besoin d'éléments factices ni d'appel .FirstOrDefault () pour chaque champ.

32
répondu salgiza 2014-06-30 11:09:17

j'ai résolu le problème en créant une surcharge de DisplayNameFor qui accepte un IPagedList<TModel>.

namespace PagedList.Mvc
{
    public static class Extensions
    {

        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
        public static MvcHtmlString DisplayNameFor<TModel, TValue>(this HtmlHelper<IPagedList<TModel>> html, Expression<Func<TModel, TValue>> expression)
        {
            return DisplayNameForInternal(html, expression);
        }

        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This is an extension method")]
        internal static MvcHtmlString DisplayNameForInternal<TModel, TValue>(this HtmlHelper<IPagedList<TModel>> html, Expression<Func<TModel, TValue>> expression)
        {
            return DisplayNameHelper(ModelMetadata.FromLambdaExpression(expression, new ViewDataDictionary<TModel>()),
                                     ExpressionHelper.GetExpressionText(expression));
        }

        internal static MvcHtmlString DisplayNameHelper(ModelMetadata metadata, string htmlFieldName)
        {
            string resolvedDisplayName = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();

            return new MvcHtmlString(HttpUtility.HtmlEncode(resolvedDisplayName));
        }
    }
}

je vais envoyer une demande de pull au projet PageList pour l'inclure dans le projet pour tout le monde.

4
répondu CodeClimber 2015-02-10 14:43:26

Vous n'avez pas besoin de changer @Html.DisplayNameFor. Déclarer modèle dans la vue:

@model IEnumerable<Dossier.Models.Item>

déplacez simplement votre pager en vue partielle (nommez-le "_Pager"):

@model IPagedList

...

@Html.PagedListPager(Model, 
   page => Url.Action("Index", new { page, pageSize = Model.PageSize }))

...

afficher le pager dans votre vue:

@Html.Partial("_Pager", Model)

c'est tout.

0
répondu David Dekanozishvili 2015-09-25 12:49:21