Typically when asked to display a list data, lets say customers, we create a first name column, last name column and then iterate over the rows to produce a table. Something like this:
But recently I was asked to produce a pivot of this data, putting each customer in their own column instead of an individual row. After doing the obligatory internet searching I found no solution that I really liked. So I wrote my own…
Lets start by creating our customer object:
public class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
Now that we got him, lets mock up some data in our controller:
public ActionResult Index()
{
var customers = new List<Customer>();
for (int i = 0; i < 100; i++)
{
customers.Add(new Customer()
{
Id = i,
FirstName = string.Format("First {0}", i),
LastName = string.Format("Last {0}", i),
Age = i
});
}
ViewBag.Customers = customers;
return View();
}
Finally, the meat, using a bit of reflection magic lets get a “list” of all the properties on our customer, iterate over each of them to generate our rows, then iterate over each customer and get the “value” for that row.
<div style="width: 600px; overflow: auto">
<table style="white-space: nowrap;">
<thead>
<tr>
<th></th>
@foreach (var customer in ViewBag.Customers)
{
<th style="">
Customer @customer.Id
</th>
}
</tr>
</thead>
<tbody>
@foreach (var prop in typeof(Customer).GetProperties())
{
<tr>
<td>
@prop.Name
</td>
@foreach (var customer in ViewBag.Customers)
{
<td>
@prop.GetValue(customer, null)
</td>
}
</tr>
}
</tbody>
</table>
</div>
And ta-da we have a table with dynamically generated columns based on the number of “customers” in our collection.
