À 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.
4 réponses
Vous pouvez essayer ce
@Html.DisplayNameFor(model => model.FirstOrDefault().ItemName)
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.
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.
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.