Question

I have a bunch of items that I have grouped up by Header.

I would like to display them on the page with the header text followed by the editor template for each individual item.

I tried using nested templates as follows:

Main Page:

@Html.EditorFor(x => x.GroupedItems, "ListofGrouping");

ListofGrouping Editor Template:

@model IList<IGrouping<string, Model>>
@for(int i = 0; i < Model.Count(); i++)
{
    @Html.EditorFor(x => x[i],"IGrouping")
}

IGrouping Editor Template:

@model IGrouping<string, Model>

@Html.DisplayFor(x => x.Key)
@Html.EditorForModel()

This works up till the last line. I get all the header values but the individual items are not displayed.

If I can't get it to work this way I will just use a data grid and do the grouping there, but I figured this should be possible in MVC3.

Was it helpful?

Solution

Update: You must write your own EditorTemplate for IGrouping.

Sample of EditorTemplate for IGrouping: Model:

public class Row
{
    public Row()
    {
    }

    public Row(string key, int value)
    {
        Key = key;
        Value = value;
    }

    public int Value { get; set; }

    public string Key { get; set; }
}

Controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        IEnumerable<Row> dict = new[] { new Row("1", 1), new Row("1", 2), new Row("1", 3), new Row("2", 2), new Row("2", 3), new Row("2", 4) };
        var grouped = dict.GroupBy(c => c.Key).First();
        //var grouplist = grouped.Select(c => new KeyValuePair<string, IEnumerable<int>> (c.Key, c.Select(b=>b.Value)));
        return View(grouped);
    }

    public ActionResult Post(IEnumerable<Row> Model)
    {
        return null;
    }
}

View Index:

@model IGrouping<string, MvcApplication1.Models.Row>
@{
    ViewBag.Title = "Home Page";
}

@using(Html.BeginForm("Post", "Home", FormMethod.Post))
{
    @Html.EditorForModel("IGrouping")
    <button type="submit">Submit</button>
}

EditorTemplate IGrouping.cshtml:

@model IGrouping<string, MvcApplication1.Models.Row>
@{
    @Html.DisplayFor(m => m.Key)
    int i = 0;
    foreach (var pair in Model.Select(c => c))
    {
        @Html.Hidden(string.Format("Model[{0}].Key", i), pair.Key)
        @Html.TextBox(string.Format("Model[{0}].Value", i), pair.Value)
        i++;
    }
}

More about binding Collections you can read there:Hancelman's blog

OTHER TIPS

Remember that the IGrouping is also an IEnumerable. So instead of using @Html.EditorForModel(), enumerate over the items.

@model IGrouping<string, Model>

@Html.DisplayFor(x => x.Key)
foreach (var grp in Model)
{
    @Html.EditorFor(model => grp)
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top