Dynamic columns seem to be incredibly tricky within the MVC Grid wrappers. I'm trying to build a grid where the columns represent a user-selectable range of years. As such, I have no knowledge of how many will be present at build time.
ViewModel:
<code>
public class Indicator
{
public Grid Grid { get; set; }
}
public class Grid
{
public List<string> Columns { get; set; }
public List<GridRow> Rows { get; set; }
}
public class GridRow
{
public string Label { get; set; }
public List<decimal> Values { get; set; }
public List<GridRow> ChildRows { get; set; }
}
</code>
Controller method:
<code>
public ActionResult Index()
{
Indicator i = new Indicator();
i.Grid = new Grid();
i.Grid.Columns = new List<string> { "2011", "2012", "2013", "2014", "2015" };
i.Grid.Rows = new List<GridRow>
{
new GridRow { Label = "First", Values = new List<decimal> { 5M, 2M, 1M, 8M, 10M } },
new GridRow { Label = "Second", Values = new List<decimal> { 2M, 2M, 4M, 8M, 9M } },
new GridRow { Label = "Third", Values = new List<decimal> { 12M, 8M, 1M, 9M, 3M } }
};
return View(i);
}
</code>
View:
<code>
@model MyProject.ViewModels.Indicator
@(Html.Kendo().Grid(Model.Grid.Rows)
.Name("testGrid")
.Columns(columns =>
{
columns.Bound(r => r.Label).Title("Type");
int i = -1;
foreach (var c in Model.Grid.Columns) {
++i;
columns.Bound(r => r.Values.ElementAt(i)).Title(c);
}
})
)
</code>
The problem is that r.Values.ElementAt(i) dies with: Bound columns require a field or property access expression. If I create a complex object in place of the list of decimals, I can then address a decimal field directly. However, this seems convoluted. Also, if I try to run .Format("{0}") at that point, 0 is the only element I can address and it points back to the first item in the List of complex objects, therefore printing that value across all columns.
I'm having a hard time wrapping my head around how to get a dynamic number of columns into the Grid in a usable fashion.
ViewModel:
<code>
public class Indicator
{
public Grid Grid { get; set; }
}
public class Grid
{
public List<string> Columns { get; set; }
public List<GridRow> Rows { get; set; }
}
public class GridRow
{
public string Label { get; set; }
public List<decimal> Values { get; set; }
public List<GridRow> ChildRows { get; set; }
}
</code>
Controller method:
<code>
public ActionResult Index()
{
Indicator i = new Indicator();
i.Grid = new Grid();
i.Grid.Columns = new List<string> { "2011", "2012", "2013", "2014", "2015" };
i.Grid.Rows = new List<GridRow>
{
new GridRow { Label = "First", Values = new List<decimal> { 5M, 2M, 1M, 8M, 10M } },
new GridRow { Label = "Second", Values = new List<decimal> { 2M, 2M, 4M, 8M, 9M } },
new GridRow { Label = "Third", Values = new List<decimal> { 12M, 8M, 1M, 9M, 3M } }
};
return View(i);
}
</code>
View:
<code>
@model MyProject.ViewModels.Indicator
@(Html.Kendo().Grid(Model.Grid.Rows)
.Name("testGrid")
.Columns(columns =>
{
columns.Bound(r => r.Label).Title("Type");
int i = -1;
foreach (var c in Model.Grid.Columns) {
++i;
columns.Bound(r => r.Values.ElementAt(i)).Title(c);
}
})
)
</code>
The problem is that r.Values.ElementAt(i) dies with: Bound columns require a field or property access expression. If I create a complex object in place of the list of decimals, I can then address a decimal field directly. However, this seems convoluted. Also, if I try to run .Format("{0}") at that point, 0 is the only element I can address and it points back to the first item in the List of complex objects, therefore printing that value across all columns.
I'm having a hard time wrapping my head around how to get a dynamic number of columns into the Grid in a usable fashion.