48

我一直在尝试 PagedList 包来为我的索引视图获取分页。一切进展顺利,在控制器级别一切正常,每页仅显示 5 条记录,并根据查询字符串显示适当的页面。

我的问题在视图中。我将 @Model 更改为,PagedList.IPagedList以便可以访问Model.HasNextPage和其他属性,但现在@Html.DisplayNameFor(model => model.ItemName)不再工作。我收到此错误:

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?)

以下是视图的相关部分:

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

...

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

似乎 IPagedList 与 DisplayNameFor() 不兼容。知道为什么会发生这种情况,以及我该如何解决?我知道我可以手动输入列名,但我希望该信息稍后保留(并且可以更改)在模型中。

4

5 回答 5

84

你可以试试这个

@Html.DisplayNameFor(model => model.FirstOrDefault().ItemName)
于 2013-02-27T01:35:18.820 回答
43

作为已接受答案的替代解决方案,请记住 IPagedList 继承自 IEnumerable。这意味着你可以写:

@model IEnumerable<Dossier.Models.Item>

在页面的开头,并在需要时将模型转换为 IPagedList:

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

您甚至可以在标题中声明转换变量,以便在页面中多次使用它:

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

这将允许您使用 DisplayNameFor 辅助方法,并访问所有 PagedList 方法/属性,而无需虚拟元素,也无需为每个字段调用 .FirstOrDefault()。

于 2014-06-30T11:09:17.580 回答
4

我通过创建一个DisplayNameFor接受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));
        }
    }
}

我将向 PageList 项目发送一个拉取请求,以将其包含到每个人的项目中。

于 2015-02-10T14:43:26.730 回答
1

你不需要改变@Html.DisplayNameFor。在视图中声明模型为:

@model IEnumerable<Dossier.Models.Item>

只需将您的寻呼机移动到局部视图(让我们将其命名为“_Pager”):

@model IPagedList

...

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

...

在您的视图中渲染寻呼机:

@Html.Partial("_Pager", Model)

就是这样。

PS 您可以创建 Html 助手而不是部分视图...

于 2015-09-25T12:49:21.463 回答
0

作为替代解决方案,您可以尝试:

@Html.DisplayNameFor(x => x.GetEnumerator().Current.ItemName)

即使列表为空,它也会起作用!

于 2020-05-05T21:16:05.183 回答