Sunday, February 3, 2008

New requirements poured in last week and one among them was to transpose a DataGrid by interchanging rows to columns and columns to rows. The usability engineer proposed that, by doing so, would enable him to utilize the recovered empty spaces on the screen to group data more efficiently. As you know, there is no straightforward way to flip a grid by setting a property or so. I googled to see if there were any solutions already implemented by fellow .NET'ers to address this requirement and found an impressive article on Code Project. Well, I was looking for a much simpler solution and eventually decided to do it myself. It didn't take any longer than I spent googling. The idea is straight and simple, transpose the DataTable and bind it to the grid.

To demonstrate this approach, I'll first start by creating a sample DataTable with 3 columns and 5 rows using the code shown below.

The column headers are numbered by default. You can hide them by setting ShowHeader="false" which would render a grid as shown below.

First Name

Firstname1

Firstname2

Firstname3

Firstname4

Firstname5

Last Name

Lastname1

Lastname2

Lastname3

Lastname4

Lastname5

Age

10

20

30

40

50

Now, let's make the first column elements bold indicating that they're the new "headers" for the transposed grid. This could be tricky with the AutoGenerated columns as we don't have explicit control over them. By default, the HtmlEncode property on these columns are set to "True". This rules out an option of enclosing texts with HTML tags (<B></B>) when the columns are autogenerated.

newRow[0] = "<B>"+dt.Columns[i].ColumnName+"</B>";

This would render an ugly looking grid as shown below...

<B>First Name</B>

Firstname1

Firstname2

Firstname3

Firstname4

Firstname5

<B>Last Name</B>

Lastname1

Lastname2

Lastname3

Lastname4

Lastname5

<B>Age</B>

10

20

30

40

50

Moreover, the GridView column collection will not have autogenerated columns, that is, their count is 0. This rules out another option of looping through the columns and selectively setting the properties. However, by setting the AutoGenerateColumns property to False and dynamically creating bound columns, with HtmlEncode = "false", would give us more flexibility. The GenerateGridColumns() method that's shown below loops through each column in the transposed table, creates a BoundField and adds it to the GridView's DataControlFieldCollection.