[Download Code]
The output of the pivot method is a new DataTable with one row for each column of the input table, and one column for each Product represented by the rows of the input table. To simplify this example, we assume that the "Product" column is the first column of each row (Column[0]), and the remaining columns represent the features.
The first step is to create the new DataTable and its schema from the rows of the input table. The first column is for the Feature description, and the remaining columns are the Product names found in each row of the input. In the following code snippet, source refers to the input table and dest is the new pivoted table.
DataTable dest = new DataTable("Pivot" + source.TableName );
// 1st column is for the feature descriptions
dest.Columns.Add( "Features" );
// the remaining columns are Product Description
// from each source table row (1st column)
foreach( DataRow r in source.Rows )
dest.Columns.Add( r[0].ToString() );
// assign each row the Product name
Now that we have the appropriate columns defined in the schema of the destination table, the next step is to create a DataRow for each feature defined in the columns of the source table, excluding the first column representing the Product name.
for( int i = 0; i < source.Columns.Count - 1; i++ )
dest.Rows.Add( dest.NewRow() );
The final step is the actual transform of the columns from the source rows into the destination table. Since each table now represents a two dimensional array of its rows and columns, a very simple transform of all columns and rows could be performed by the following nested for loop.
for( int r = 0; r < dest.Rows.Count; r++ )
for( int c = 0; c < source.Columns.Count; c++ )
dest.Rows[r][c] = source.Rows[c][r];
However, this simple loop doesn't account for the first column of the destination representing the Feature description from the source columns. So we modify the code slightly as shown in this code snippet.
for( int r = 0; r < dest.Rows.Count; r++ )
for( int c = 0; c < source.Columns.Count; c++ )
if ( c == 0 ) dest.Rows[r][0] = source.Columns[r + 1].ColumnName;
else dest.Rows[r][c] = source.Rows[c - 1][r + 1];
Now that we have our pivoted DataTable ready to display, we could simply bind it to a DataGrid; however, our client wants the DataGrid to page, rather than scroll horizontally to show a limited number of products on each page. The technique used to implement this feature is illustrated on the next page.