1

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.

Kirill Bestemyanov
  • 11,946
  • 2
  • 24
  • 38
Kelly
  • 3,292
  • 1
  • 24
  • 24

2 Answers2

0

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

Kirill Bestemyanov
  • 11,946
  • 2
  • 24
  • 38
  • That's actually a built in template, it should work with or without the "Collection" parameter. – Kelly Sep 07 '12 at 19:53
  • "Collection" parameter means that you use EditorTemplate Collection.cshtml for your model, where your model is IGrouping. – Kirill Bestemyanov Sep 07 '12 at 23:21
  • I update my post with working sample. I hope it will help you. – Kirill Bestemyanov Sep 07 '12 at 23:52
  • To your first comment, yes understand that. Using the Collection template for IGrouping should work just fine because IGrouping implements IEnumerable (http://msdn.microsoft.com/en-us/library/bb344977.aspx). I will reply to your updated answer in another comment. – Kelly Sep 10 '12 at 14:43
  • Your updated answer will work, however it does not allow me to use the Editor template that I created for my Model. I will mark this as correct if no one can figure out a way to make this work with an Editor template (for the individual Model objects). – Kelly Sep 10 '12 at 14:45
  • I can help you with your editor template if you show it. I assume that you can use it through extension method to html helper. – Kirill Bestemyanov Sep 10 '12 at 15:12
  • The editor template is fine (I'm using it on another screen already). The problem is using it in this scenario. I tried @dbaseman method but the framework seems to ignore that. I never get any errors, the items just don't show up. – Kelly Sep 10 '12 at 15:25
0

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)
}
McGarnagle
  • 101,349
  • 31
  • 229
  • 260