This is a migrated thread and some comments may be shown as answers.

Dynamic columns based on List in ViewModel

1 Answer 1334 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Micah
Top achievements
Rank 1
Micah asked on 15 Aug 2014, 06:39 PM
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.




1 Answer, 1 is accepted

Sort by
0
Accepted
Rosen
Telerik team
answered on 19 Aug 2014, 07:28 AM
Hi Micah,

In this case you will need to use Template instead of a Bound column. The tricky part will be to capture the state of the index within the Func used as the template:

@model GridDynamicColumns.Models.Indicator
 
@(Html.Kendo().Grid(Model.Grid.Rows)
    .Name("testGrid")
    .Columns(columns =>
    {
        columns.Bound(r => r.Label).Title("Type");
        for (int i = 0; i < Model.Grid.Columns.Count; i++)
        {
            var index = i;
            columns.Template(@<text>@item.Values[index].ToString("c")</text>).Title(Model.Grid.Columns[i]);
        }
        
    })


Regards,
Rosen
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
Grid
Asked by
Micah
Top achievements
Rank 1
Answers by
Rosen
Telerik team
Share this question
or