In this article I will explain how to Rotate / Flip / Transpose GridView - Convert GridView Columns to Rows and Rows to Columns by rotating DataTable using C# and VB.Net.
This article also explains how to get back the original GridView from the Rotated / Flipped / Transposed DataTable using C# and VB.Net.
I am making use of a GridView control to display the Rotated / Flipped / Transposed DataTable.
 
HTML Markup
Below is the HTML Markup where I have an ASP.Net GridView Control and two buttons one to Rotate / Flip / Transpose DataTable Columns to Rows and another to Rotate / Flip / Transpose DataTable rows to Columns
<asp:GridView ID="GridView1" CssClass="Grid" HeaderStyle-CssClass="header" runat="server"
    AutoGenerateColumns="true">
</asp:GridView>
<br />
<asp:Button ID="btnConvert1" runat="server" Text="Convert Rows to Columns" OnClick="Convert"
    CommandArgument="1" />
<asp:Button ID="btnConvert2" runat="server" Text="Convert Columns to Rows" OnClick="Convert"
    CommandArgument="2" Visible="false" />
 
 
Namespaces
You will need to import the following namespaces
C#
using System.Data;
 
VB.Net
Imports System.Data
 
 
Binding the ASP.Net GridView Control
Below is the code to bind the ASP.Net GridView. You will notice that I am saving the DataTable to ViewState variable so that it can be reused later on.
The BindGrid method accepts an additional parameter rotate based on which I hide and show the GridView headers.
C#
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        DataTable dt = new DataTable();
        dt.Columns.AddRange(new DataColumn[3] { new DataColumn("Item"), new DataColumn("Quantity"), new DataColumn("Price") });
        dt.Rows.Add("Shirt", 145, 500);
        dt.Rows.Add("Jeans", 0, 2000);
        dt.Rows.Add("Trousers", 190, 1545);
        dt.Rows.Add("Tie", 30, 200);
        dt.Rows.Add("Cap", 0, 300);
        dt.Rows.Add("Hat", 90, 350);
        dt.Rows.Add("Scarf", 290, 140);
        dt.Rows.Add("Belt", 150, 400);
        ViewState["dt"] = dt;
        BindGrid(dt, false);
    }
}
 
private void BindGrid(DataTable dt, bool rotate)
{
    GridView1.ShowHeader = !rotate;
    GridView1.DataSource = dt;
    GridView1.DataBind();
    if (rotate)
    {
        foreach (GridViewRow row in GridView1.Rows)
        {
            row.Cells[0].CssClass = "header";
        }
    }
}
 
VB.Net
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    If Not IsPostBack Then
        Dim dt As New DataTable()
        dt.Columns.AddRange(New DataColumn(2) {New DataColumn("Item"), New DataColumn("Quantity"), New DataColumn("Price")})
        dt.Rows.Add("Shirt", 145, 500)
        dt.Rows.Add("Jeans", 0, 2000)
        dt.Rows.Add("Trousers", 190, 1545)
        dt.Rows.Add("Tie", 30, 200)
        dt.Rows.Add("Cap", 0, 300)
        dt.Rows.Add("Hat", 90, 350)
        dt.Rows.Add("Scarf", 290, 140)
        dt.Rows.Add("Belt", 150, 400)
        ViewState("dt") = dt
        BindGrid(dt, False)
    End If
End Sub
 
Private Sub BindGrid(dt As DataTable, rotate As Boolean)
    GridView1.ShowHeader = Not rotate
    GridView1.DataSource = dt
   GridView1.DataBind()
    If rotate Then
        For Each row As GridViewRow In GridView1.Rows
            row.Cells(0).CssClass = "header"
        Next
    End If
End Sub
 
 
Rotate / Flip / Transpose DataTable Columns to Rows and Rows to Columns using C# and VB.Net
In the below code I am making use of two DataTables, one the original one from ViewState variable and other one I would use to store the rotated / flipped / transposed rows.
Then finally the rotated / flipped / transposed DataTable is bound to the ASP.Net GridView Control
C#
protected void Convert(object sender, EventArgs e)
{
    DataTable dt = (DataTable)ViewState["dt"];
    if ((sender as Button).CommandArgument == "1")
    {
        btnConvert1.Visible = false;
        btnConvert2.Visible = true;
        DataTable dt2 = new DataTable();
        for (int i = 0; i <= dt.Rows.Count; i++)
        {
            dt2.Columns.Add();
        }
        for (int i = 0; i < dt.Columns.Count; i++)
        {
            dt2.Rows.Add();
            dt2.Rows[i][0] = dt.Columns[i].ColumnName;
        }
        for (int i = 0; i < dt.Columns.Count; i++)
        {
            for (int j = 0; j < dt.Rows.Count; j++)
            {
                dt2.Rows[i][j + 1] = dt.Rows[j][i];
            }
        }
        BindGrid(dt2, true);
    }
    else
    {
        btnConvert1.Visible = true;
        btnConvert2.Visible = false;
        BindGrid(dt, false);
    }
}
 
VB.Net
Protected Sub Convert(sender As Object, e As EventArgs)
    Dim dt As DataTable = DirectCast(ViewState("dt"), DataTable)
    If TryCast(sender, Button).CommandArgument = "1" Then
        btnConvert1.Visible = False
        btnConvert2.Visible = True
        Dim dt2 As New DataTable()
        For i As Integer = 0 To dt.Rows.Count
            dt2.Columns.Add()
        Next
        For i As Integer = 0 To dt.Columns.Count - 1
            dt2.Rows.Add()
            dt2.Rows(i)(0) = dt.Columns(i).ColumnName
        Next
        For i As Integer = 0 To dt.Columns.Count - 1
            For j As Integer = 0 To dt.Rows.Count - 1
                dt2.Rows(i)(j + 1) = dt.Rows(j)(i)
            Next
        Next
        BindGrid(dt2, True)
    Else
        btnConvert1.Visible = True
        btnConvert2.Visible = False
        BindGrid(dt, False)
    End If
End Sub
 
 
Demo
 
Downloads