I have two entities Competencies and Roles. These are both created by the user and stored in the database.
On a specific screen the user select certain Competencies and certain Roles. These then have to be displayed in a matrix.
They will then use check boxes to link the Competencies and Roles.
Each competency will be linked to several of the roles.
This matrix is completely dynamic as I do not know how many
columns there will be or the names of the columns.
I know that there will be a
Competency Id column and a Competency Name column. Each row will have one or
more roles.
We use kendo grids throughout the application so I want to use
a kendo grid.
I have tried many different ways of doing this. I have
successfully passed in a System.Data.DataTable which works but is
cumbersome to create. We use NHibernate and it is easier to create a model. The
most successful way that I have that uses a model is as follows:
public class BasicRowModel
{
public string CompetencyId { get; set; }
public string CompetencyName { get; set; }
public List<BasicTrainingRoleModel> Roles { get; set; }
}
public class BasicTrainingRoleModel
{
public string RoleName { get; set; }
public bool RoleVal { get; set; }
}
My view is as follows:
@model IEnumerable<BasicRowModel>
@using Models
@using System.Linq;
@{
ViewBag.Title = "DynamicGrid2";
}
<h2>DynamicGrid2</h2>
@section
scripts
{
<script type="text/javascript" src="@Url.Content("~/Scripts/Training.js")"></script>
}
@{
ViewBag.Title = "Administration";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@(Html.Kendo().Grid(Model)
.Name("RoleCompsTable")
.Columns(columns =>
{
columns.Bound(r => r.CompetencyId)
.Hidden();
columns.Bound(r => r.CompetencyName)
.Title("Competency");
for (int c = 0; c < ViewBag.RoleCount; c++)
{
//columns.Template(@<text>@item.Roles[c].RoleVal.ToString()</text>).Title(ViewBag.Roles[c]);
columns.Bound(r =>
r.Roles[c].RoleVal).Title(ViewBag.Roles[c]);
}
//columns.Bound(r
=> r.Roles[0].RoleVal).Title(ViewBag.Roles[0]);
//columns.Bound(r
=> r.Roles[1].RoleVal).Title(ViewBag.Roles[1]);
//columns.Bound(r
=> r.Roles[2].RoleVal).Title(ViewBag.Roles[2])
}))
The for loop does not work with either the columns.Bound or
the template. It results in an out of range error. When stepping into this code
it works fine but it is afterwards that the error occurs.
Exception Details: System.ArgumentOutOfRangeException:
Index was out of range. Must be non-negative and less than the size of the
collection.
Parameter name: index
Source Error:
Line 31: for (int c = 0; c <
ViewBag.RoleCount; c++)
Line 32: {
Line 33:columns.Template(@<text>@item.Roles[c].RoleVal.ToString()</text>).Title(ViewBag.Roles[c]);
Line 34: //columns.Bound(r =>
r.Roles[c].RoleVal).Title(ViewBag.Roles[c]);
Line 35: }
When I comment out the for loop and uncomment the columns.Bound
lines it works perfectly with the attached result. Obviously this is not a
solution for me as it is dynamic and I do not know how many columns there will
be. Why does the for loop not work for this?
Regards
Tyler