Why is my DisplayFor not looping through my IEnumerable?

前端 未结 4 1465
难免孤独
难免孤独 2020-12-06 05:19

I have this line in my view

@(Html.DisplayFor(m => m.DaysOfWeek, \"_CourseTableDayOfWeek\"))

where m.DaysOfWeek is a

相关标签:
4条回答
  • 2020-12-06 05:23

    Use FilterUIHint instead of the regular UIHint, on the IEnumerable<T> property.

    public class MyModel
    {
        [FilterUIHint("_CourseTableDayOfWeek")]
        public IEnumerable<DateTime> DaysOfWeek { get; set; }
    }
    

    No need for anything else.

    @Html.DisplayFor(m => m.DaysOfWeek)
    

    This now displays an "_CourseTableDayOfWeek" EditorTemplate for each DateTime in DaysOfWeek.

    0 讨论(0)
  • 2020-12-06 05:29

    A minor tweak to allow this to Dan's solution to be a little more generic:

    public static class DisplayTextListExtension
        {
            public static MvcHtmlString DisplayForList<TModel, 
    EModel>(this HtmlHelper<TModel> html, IEnumerable<EModel> model, string templateName)
            {
                var tempResult = new StringBuilder();
    
                foreach (var item in model)
                {
                    tempResult.Append(html.DisplayFor(m => item, templateName));
                }
    
                return MvcHtmlString.Create(tempResult.ToString());
            }
        }
    
    0 讨论(0)
  • 2020-12-06 05:32

    It's not looping because you have specified a name for the display template as second argument of the DisplayFor helper (_CourseTableDayOfWeek).

    It loops only when you rely on conventions i.e.

    @Html.DisplayFor(m => m.DaysOfWeek)
    

    and then inside ~/Views/Shared/DisplayTemplates/DateTime.cshtml:

    @model DateTime
    @{
        ViewBag.Title = "CourseTableDayOfWeek";
    }
    <th>
        @System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.DayNames[(int) Model.DayOfWeek]
        <span class="dateString">Model.ToString("G")</span>
    </th>
    

    Once you specify a custom name for the display template (either as second argument of the DisplayFor helper or as [UIHint] attribute) it will no longer loop for collection properties and the template will simply be passed the IEnumerable<T> as model.

    It's confusing but that's how it is. I don't like it either.

    0 讨论(0)
  • 2020-12-06 05:32

    This seems like a bug. Html Helper classes are easy to extend, although after looking at the MVC source, looking for the bug, I gave up and just leveraged the premise that templates work for an individual item, so I wrote an HtmlHelper extension that wraps it for you. I took out the lambda expression for my own simplicity, but you can easily go back to that. This example is just for a list of strings.

        public static class DisplayTextListExtension
    {
        public static MvcHtmlString DisplayForList<TModel>(this HtmlHelper<TModel> html, IEnumerable<string> model, string templateName)
        {
            var tempResult = new StringBuilder();
    
            foreach (var item in model)
            {
                tempResult.Append(html.DisplayFor(m => item, templateName));
            }
    
            return MvcHtmlString.Create(tempResult.ToString());
        }
    }
    

    Then the actual usage looks like:

                                    @Html.DisplayForList(Model.Organizations, "infoBtn")
    
    0 讨论(0)
提交回复
热议问题