Tuesday 21 December 2010

How to create multiple row header and merge it with other columns in GridView


In sometime showing single header is not enough in our application and we might require showing more than one header to categorize the columns. This blog concentrates on how to design the ASP.NET GridView control to have more than one row header.

Before going for implementation let us understand the actual requirement we are going to implement in this post,

I have an XML file in my project which has five columns. The screen short of the records are:
Excel sheet screen shot of the data

The XML file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<RevenueReport>
  
  <Data Year="2008" Period="Q1" AuditedBy="Maria Anders" DirectRevenue="12500.00" ReferralRevenue="2500.00" />
  <Data Year="2008" Period="Q2" AuditedBy="Ana Trujillo" DirectRevenue="21000.00" ReferralRevenue="8000.00" />
  <Data Year="2008" Period="Q3" AuditedBy="Antonio Moreno" DirectRevenue="20000.00" ReferralRevenue="5000.00" />
  <Data Year="2008" Period="Q4" AuditedBy="Thomas Hardy" DirectRevenue="25000.00" ReferralRevenue="1200.00" />

  <Data Year="2009" Period="Q1" AuditedBy="Christina Berglund" DirectRevenue="72500.00" ReferralRevenue="5000.00" />
  <Data Year="2009" Period="Q2" AuditedBy="Hanna Moos" DirectRevenue="15000.00" ReferralRevenue="6500.00" />
  <Data Year="2009" Period="Q3" AuditedBy="Thomas Hardy" DirectRevenue="25000.00" ReferralRevenue="1520.00" />
  <Data Year="2009" Period="Q4" AuditedBy="Martín Sommer" DirectRevenue="42000.00" ReferralRevenue="2580.00" />

  <Data Year="2010" Period="Q1" AuditedBy="Laurence Lebihan" DirectRevenue="12500.00" ReferralRevenue="1500.00" />
  <Data Year="2010" Period="Q2" AuditedBy="Elizabeth Lincoln" DirectRevenue="25000.00" ReferralRevenue="5500.00" />
  <Data Year="2010" Period="Q3" AuditedBy="Hanna Moos" DirectRevenue="12000.00" ReferralRevenue="1800.00" />
  <Data Year="2010" Period="Q4" AuditedBy="Antonio Moreno" DirectRevenue="10000.00" ReferralRevenue="1200.00" />
  
</RevenueReport>

I required of Grid View is

Required output of the GridView

To implement this requirement, we have to follow the same concept we normally implement for html table with colspan and rowspan attributes.

The following points explains the same:

  1. Initially when we bind the records to GridView, the page will be like the following image. (Here the Direct, Referral, Total heading has bound using XML file column name, we have to change the heading to what explained before)

    Normal GridView output (bind from XML file)
  2. For .NET runtime, header is also a row. So once the header row created, we have to manually add one more row above the header which has been created by .NET runtime and add required columns by merging with other columns. To do this we have to use the RowCreated event on GridView. The output will be as follows:

    After adding one more row on top of the actual header and merging the columns
    Here the first row created and added by our program code.
  3. Here, the first three columns are required to be merged with row (means first row Year, second row Year cells required to be merged). But the second row Year cell already created by normal binding method (using .NET runtime). So to achieve this, we required to Invisible (hide) the second row Year cell. The same will applied for Period and Audited By columns.

    To do this we can use RowDataBound event of GridView. The final output is below.

    After merging first three columns with its next row

The implementation is follows:

GridView Script

<asp:GridView ID="grdViewProducts" runat="server" AutoGenerateColumns="False" TabIndex="1"
    Width="100%" DataSourceID="XmlDataSource1" ShowFooter="false" 
    CellPadding="4" ForeColor="Black" GridLines="Vertical" 
    BackColor="White" BorderColor="#DEDFDE" BorderStyle="None" BorderWidth="1px" 
    OnRowDataBound="grdViewProducts_RowDataBound" 
    onrowcreated="grdViewProducts_RowCreated" >
    <RowStyle BackColor="#F7F7DE" />
    <Columns>
        <asp:BoundField DataField="Year" HeaderText="Year" ItemStyle-HorizontalAlign="Left" >
        </asp:BoundField>
        <asp:BoundField DataField="Period" HeaderText="Period" ItemStyle-HorizontalAlign="Left" >
        </asp:BoundField>
        <asp:BoundField DataField="AuditedBy" HeaderText="Audited By" ItemStyle-HorizontalAlign="Left" >
        </asp:BoundField>
        <asp:BoundField DataField="DirectRevenue" HeaderText="Direct" ItemStyle-HorizontalAlign="Right" >
        </asp:BoundField>
        <asp:BoundField DataField="ReferralRevenue" HeaderText="Referral" ItemStyle-HorizontalAlign="Right" >
        </asp:BoundField>
        <asp:TemplateField HeaderText="Total">
            <ItemStyle HorizontalAlign="Right" />
            <ItemTemplate>
                <asp:Label runat="server" ID="lblTotalRevenue" Text="0" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    
    <FooterStyle BackColor="#CCCC99" />
    <PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" />
    <SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" />
    <HeaderStyle CssClass="HeaderStyle" />
    <AlternatingRowStyle BackColor="White" />
</asp:GridView>
<asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="Data/RevenueReport.xml"></asp:XmlDataSource>

Code behind Code

protected void grdViewProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // Invisibling the first three columns of second row header (normally created on binding)
    if (e.Row.RowType == DataControlRowType.Header)
    {
        e.Row.Cells[0].Visible = false; // Invisibiling Year Header Cell
        e.Row.Cells[1].Visible = false; // Invisibiling Period Header Cell
        e.Row.Cells[2].Visible = false; // Invisibiling Audited By Header Cell
    }

    // This is for calculation of last column (Total = Direct + Referral)
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        double dblDirectRevenue = Convert.ToDouble(DataBinder.Eval(e.Row.DataItem, "DirectRevenue").ToString());
        double dblReferralRevenue = Convert.ToDouble(DataBinder.Eval(e.Row.DataItem, "ReferralRevenue").ToString());
        Label lblTotalRevenue = ((Label)e.Row.FindControl("lblTotalRevenue"));
        lblTotalRevenue.Text = string.Format("{0:0.00}", (dblDirectRevenue + dblReferralRevenue));
    }
}

protected void grdViewProducts_RowCreated(object sender, GridViewRowEventArgs e)
{
    // Adding a column manually once the header created
    if (e.Row.RowType == DataControlRowType.Header) // If header created
    {
        GridView ProductGrid = (GridView)sender;

        // Creating a Row
        GridViewRow HeaderRow = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert);

        //Adding Year Column
        TableCell HeaderCell = new TableCell();
        HeaderCell.Text = "Year";
        HeaderCell.HorizontalAlign = HorizontalAlign.Center;
        HeaderCell.RowSpan = 2; // For merging first, second row cells to one
        HeaderCell.CssClass = "HeaderStyle";
        HeaderRow.Cells.Add(HeaderCell);

        //Adding Period Column
        HeaderCell = new TableCell();
        HeaderCell.Text = "Period";
        HeaderCell.HorizontalAlign = HorizontalAlign.Center;
        HeaderCell.RowSpan = 2;
        HeaderCell.CssClass = "HeaderStyle";
        HeaderRow.Cells.Add(HeaderCell);

        //Adding Audited By Column
        HeaderCell = new TableCell();
        HeaderCell.Text = "Audited By";
        HeaderCell.HorizontalAlign = HorizontalAlign.Center;
        HeaderCell.RowSpan = 2;
        HeaderCell.CssClass = "HeaderStyle";
        HeaderRow.Cells.Add(HeaderCell);

        //Adding Revenue Column
        HeaderCell = new TableCell();
        HeaderCell.Text = "Revenue";
        HeaderCell.HorizontalAlign = HorizontalAlign.Center;
        HeaderCell.ColumnSpan = 3; // For merging three columns (Direct, Referral, Total)
        HeaderCell.CssClass = "HeaderStyle";
        HeaderRow.Cells.Add(HeaderCell);

        //Adding the Row at the 0th position (first row) in the Grid
        ProductGrid.Controls[0].Controls.AddAt(0, HeaderRow);
    }
}

Style Sheet

.HeaderStyle{
    border:solid 1px White;
    background-color:#81BEF7;
    font-weight:bold;
    text-align:center;
}

Here are the outputs of our example:

Output of Adding two row header and merging with adjacent cells



Merging rows in GridView


Let us take the same example and extend to get the row header.

To understand the requirement, we are going to merge the Year columns. If the same year repeats for next row, it needs to be merged. To achieve this, we can use DataBound event of GridView.

The C# implementation goes as below (the other events are same as described first example):

protected void grdViewProducts_DataBound(object sender, EventArgs e)
{
    //Starting from last Row Previous Row (if 12 rows in our grid)
    // merging last row and last previous row if same value (take 12, 11 and merge if same year)
    // Then last previous row with second last previous row (take 11, 10 and merge if same year)
    // etc., till first row and second row merging
    for (int rowIndex = grdViewProducts.Rows.Count - 2; rowIndex >= 0; rowIndex--)
    {
        GridViewRow row = grdViewProducts.Rows[rowIndex];
        GridViewRow previousRow = grdViewProducts.Rows[rowIndex + 1];
        if (row.Cells[0].Text == previousRow.Cells[0].Text)
        {
            if (previousRow.Cells[0].RowSpan < 2)
            {
                row.Cells[0].RowSpan = 2;
            }
            else
            {
                row.Cells[0].RowSpan = previousRow.Cells[0].RowSpan + 1;
            }
            previousRow.Cells[0].Visible = false;
        }
        row.Cells[0].CssClass = "HeaderStyle"; // This is to just give header color, font style
    }
}

We have to register DataBound event in the GridView script also

<asp:GridView ID="grdViewProducts" runat="server" AutoGenerateColumns="False" TabIndex="1"
    Width="100%" DataSourceID="XmlDataSource1" ShowFooter="false" 
    CellPadding="4" ForeColor="Black" GridLines="Vertical" 
    BackColor="White" BorderColor="#DEDFDE" BorderStyle="None" BorderWidth="1px" 
    OnRowDataBound="grdViewProducts_RowDataBound" 
    onrowcreated="grdViewProducts_RowCreated" 
    ondatabound="grdViewProducts_DataBound" >
    <RowStyle BackColor="#F7F7DE" />
    <Columns>
        <asp:BoundField DataField="Year" HeaderText="Year" ItemStyle-HorizontalAlign="Left" >
        </asp:BoundField>
        <asp:BoundField DataField="Period" HeaderText="Period" ItemStyle-HorizontalAlign="Left" >
        </asp:BoundField>
        <asp:BoundField DataField="AuditedBy" HeaderText="Audited By" ItemStyle-HorizontalAlign="Left" >
        </asp:BoundField>
        <asp:BoundField DataField="DirectRevenue" HeaderText="Direct" ItemStyle-HorizontalAlign="Right" >
        </asp:BoundField>
        <asp:BoundField DataField="ReferralRevenue" HeaderText="Referral" ItemStyle-HorizontalAlign="Right" >
        </asp:BoundField>
        <asp:TemplateField HeaderText="Total">
            <ItemStyle HorizontalAlign="Right" />
            <ItemTemplate>
                <asp:Label runat="server" ID="lblTotalRevenue" Text="0" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    
    <FooterStyle BackColor="#CCCC99" />
    <PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" />
    <SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" />
    <HeaderStyle CssClass="HeaderStyle" />
    <AlternatingRowStyle BackColor="White" />
</asp:GridView>
<asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="Data/RevenueReport.xml"></asp:XmlDataSource>

Here are the outputs of our example:

Output of merging adjacent rows to get Row header (adding to first example)


Three row header in GridView


Our Next example is formatting the GridView with three headers. To understand better, below is the requirement:

  1. The Data which binds to the Grid is
    Excel sheet screen shot of Records
    .
  2. Below shows the XML file
    <?xml version="1.0" encoding="utf-8" ?>
    <RevenueReport>
      
      <Data Year="2008" Period="Q1" AuditedBy="Maria Anders" HeadOfficeDirectDebit="2000.00" HeadOfficeReferralDebit="1000.00" HeadOfficeDirectCredit="22000.00" HeadOfficeReferralCredit="5220.00" BranchOfficeDirectDebit="1000.00" BranchOfficeReferralDebit="1200.00" BranchOfficeDirectCredit="12500.00" BranchOfficeReferralCredit="10500.00" />
      <Data Year="2008" Period="Q2" AuditedBy="Ana Trujillo" HeadOfficeDirectDebit="1200.00" HeadOfficeReferralDebit="2200.00" HeadOfficeDirectCredit="25000.00" HeadOfficeReferralCredit="7320.00" BranchOfficeDirectDebit="1200.00" BranchOfficeReferralDebit="1400.00" BranchOfficeDirectCredit="22500.00" BranchOfficeReferralCredit="12500.00" />
      <Data Year="2008" Period="Q3" AuditedBy="Antonio Moreno" HeadOfficeDirectDebit="2300.00" HeadOfficeReferralDebit="1300.00" HeadOfficeDirectCredit="21000.00" HeadOfficeReferralCredit="7220.00" BranchOfficeDirectDebit="1200.00" BranchOfficeReferralDebit="1100.00" BranchOfficeDirectCredit="11400.00" BranchOfficeReferralCredit="22500.00" />
      <Data Year="2008" Period="Q4" AuditedBy="Thomas Hardy" HeadOfficeDirectDebit="2000.00" HeadOfficeReferralDebit="1000.00" HeadOfficeDirectCredit="22000.00" HeadOfficeReferralCredit="5220.00" BranchOfficeDirectDebit="1000.00" BranchOfficeReferralDebit="1200.00" BranchOfficeDirectCredit="12500.00" BranchOfficeReferralCredit="10500.00" />
      <Data Year="2009" Period="Q1" AuditedBy="Christina Berglund" HeadOfficeDirectDebit="3000.00" HeadOfficeReferralDebit="1500.00" HeadOfficeDirectCredit="23000.00" HeadOfficeReferralCredit="6220.00" BranchOfficeDirectDebit="1200.00" BranchOfficeReferralDebit="2200.00" BranchOfficeDirectCredit="14500.00" BranchOfficeReferralCredit="12500.00" />
      <Data Year="2009" Period="Q2" AuditedBy="Hanna Moos" HeadOfficeDirectDebit="2100.00" HeadOfficeReferralDebit="1200.00" HeadOfficeDirectCredit="24000.00" HeadOfficeReferralCredit="5520.00" BranchOfficeDirectDebit="1200.00" BranchOfficeReferralDebit="1300.00" BranchOfficeDirectCredit="14500.00" BranchOfficeReferralCredit="12500.00" />
      <Data Year="2009" Period="Q3" AuditedBy="Thomas Hardy" HeadOfficeDirectDebit="1200.00" HeadOfficeReferralDebit="1300.00" HeadOfficeDirectCredit="22000.00" HeadOfficeReferralCredit="5420.00" BranchOfficeDirectDebit="1200.00" BranchOfficeReferralDebit="1300.00" BranchOfficeDirectCredit="14500.00" BranchOfficeReferralCredit="12500.00" />
      <Data Year="2009" Period="Q4" AuditedBy="Martín Sommer" HeadOfficeDirectDebit="1200.00" HeadOfficeReferralDebit="1300.00" HeadOfficeDirectCredit="22000.00" HeadOfficeReferralCredit="5120.00" BranchOfficeDirectDebit="1600.00" BranchOfficeReferralDebit="1500.00" BranchOfficeDirectCredit="14500.00" BranchOfficeReferralCredit="13500.00" />
      <Data Year="2010" Period="Q1" AuditedBy="Laurence Lebihan" HeadOfficeDirectDebit="2100.00" HeadOfficeReferralDebit="1300.00" HeadOfficeDirectCredit="24000.00" HeadOfficeReferralCredit="5320.00" BranchOfficeDirectDebit="1200.00" BranchOfficeReferralDebit="1100.00" BranchOfficeDirectCredit="13500.00" BranchOfficeReferralCredit="11500.00" />
      <Data Year="2010" Period="Q2" AuditedBy="Elizabeth Lincoln" HeadOfficeDirectDebit="2200.00" HeadOfficeReferralDebit="1300.00" HeadOfficeDirectCredit="26400.00" HeadOfficeReferralCredit="5520.00" BranchOfficeDirectDebit="1700.00" BranchOfficeReferralDebit="1800.00" BranchOfficeDirectCredit="12500.00" BranchOfficeReferralCredit="13500.00" />
      <Data Year="2010" Period="Q3" AuditedBy="Hanna Moos" HeadOfficeDirectDebit="2100.00" HeadOfficeReferralDebit="1200.00" HeadOfficeDirectCredit="23000.00" HeadOfficeReferralCredit="5420.00" BranchOfficeDirectDebit="1500.00" BranchOfficeReferralDebit="1600.00" BranchOfficeDirectCredit="13500.00" BranchOfficeReferralCredit="13500.00" />
      <Data Year="2010" Period="Q4" AuditedBy="Antonio Moreno" HeadOfficeDirectDebit="1400.00" HeadOfficeReferralDebit="2300.00" HeadOfficeDirectCredit="11000.00" HeadOfficeReferralCredit="2320.00" BranchOfficeDirectDebit="1200.00" BranchOfficeReferralDebit="1100.00" BranchOfficeDirectCredit="12500.00" BranchOfficeReferralCredit="13500.00" />
     
    </RevenueReport>

  3. The required output is:
    Required output of three row header

The Code implementation would be as follows:
<asp:GridView ID="grdViewProducts" runat="server" AutoGenerateColumns="False" TabIndex="1"
    Width="100%" DataSourceID="XmlDataSource1" ShowFooter="false" 
    CellPadding="4" ForeColor="Black" GridLines="Vertical" 
    BackColor="White" BorderColor="#DEDFDE" BorderStyle="None" BorderWidth="1px" 
    OnRowDataBound="grdViewProducts_RowDataBound" 
    onrowcreated="grdViewProducts_RowCreated" >
    <RowStyle BackColor="#F7F7DE" />
    <Columns>
        <asp:BoundField DataField="Year" HeaderText="Year" ItemStyle-HorizontalAlign="Left" />
        <asp:BoundField DataField="Period" HeaderText="Period" ItemStyle-HorizontalAlign="Left" />
        <asp:BoundField DataField="AuditedBy" HeaderText="Audited By" ItemStyle-HorizontalAlign="Left" />
        <asp:BoundField DataField="HeadOfficeDirectDebit" HeaderText="Direct" ItemStyle-HorizontalAlign="Right" />
        <asp:BoundField DataField="HeadOfficeReferralDebit" HeaderText="Referral" ItemStyle-HorizontalAlign="Right" />
        <asp:BoundField DataField="HeadOfficeDirectCredit" HeaderText="Direct" ItemStyle-HorizontalAlign="Right" />
        <asp:BoundField DataField="HeadOfficeReferralCredit" HeaderText="Referral" ItemStyle-HorizontalAlign="Right" />
        <asp:BoundField DataField="BranchOfficeReferralDebit" HeaderText="Referral" ItemStyle-HorizontalAlign="Right" />
        <asp:BoundField DataField="BranchOfficeReferralDebit" HeaderText="Referral" ItemStyle-HorizontalAlign="Right" />
        <asp:BoundField DataField="BranchOfficeReferralDebit" HeaderText="Referral" ItemStyle-HorizontalAlign="Right" />
        <asp:BoundField DataField="BranchOfficeReferralDebit" HeaderText="Referral" ItemStyle-HorizontalAlign="Right" />
    </Columns>
    
    <FooterStyle BackColor="#CCCC99" />
    <PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" />
    <SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" />
    <HeaderStyle CssClass="HeaderStyle" />
    <AlternatingRowStyle BackColor="White" />
</asp:GridView>
<asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="Data/RevenueReport3H.xml"></asp:XmlDataSource>

protected void grdViewProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.Header)
    {
        e.Row.Cells[0].Visible = false; // Invisibiling Year Header Cell
        e.Row.Cells[1].Visible = false; // Invisibiling Period Header Cell
        e.Row.Cells[2].Visible = false; // Invisibiling Audited By Header Cell
    }
}
protected void grdViewProducts_RowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.Header)
    {
        GridView ProductGrid = (GridView)sender;
        GridViewRow HeaderRow = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert);

        //Adding Year Column
        TableCell HeaderCell = new TableCell();
        HeaderCell.Text = "Year";
        HeaderCell.HorizontalAlign = HorizontalAlign.Center;
        HeaderCell.RowSpan = 3;
        HeaderCell.CssClass = "HeaderStyle";
        HeaderRow.Cells.Add(HeaderCell);

        //Adding Period Column
        HeaderCell = new TableCell();
        HeaderCell.Text = "Period";
        HeaderCell.HorizontalAlign = HorizontalAlign.Center;
        HeaderCell.RowSpan = 3;
        HeaderCell.CssClass = "HeaderStyle";
        HeaderRow.Cells.Add(HeaderCell);

        //Adding Audited By Column
        HeaderCell = new TableCell();
        HeaderCell.Text = "Audited By";
        HeaderCell.HorizontalAlign = HorizontalAlign.Center;
        HeaderCell.RowSpan = 3;
        HeaderCell.CssClass = "HeaderStyle";
        HeaderRow.Cells.Add(HeaderCell);

        //Adding Head Office Column
        HeaderCell = new TableCell();
        HeaderCell.Text = "Head Office";
        HeaderCell.HorizontalAlign = HorizontalAlign.Center;
        HeaderCell.ColumnSpan = 4;
        HeaderCell.CssClass = "HeaderStyle";
        HeaderRow.Cells.Add(HeaderCell);

        //Adding Branch Office Column
        HeaderCell = new TableCell();
        HeaderCell.Text = "Branch Office";
        HeaderCell.HorizontalAlign = HorizontalAlign.Center;
        HeaderCell.ColumnSpan = 4;
        HeaderCell.CssClass = "HeaderStyle";
        HeaderRow.Cells.Add(HeaderCell);

        ProductGrid.Controls[0].Controls.AddAt(0, HeaderRow);

        HeaderRow = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert);

        //Adding Head Office Debit Column
        HeaderCell = new TableCell();
        HeaderCell.Text = "Debit";
        HeaderCell.HorizontalAlign = HorizontalAlign.Center;
        HeaderCell.ColumnSpan = 2;
        HeaderCell.CssClass = "HeaderStyle";
        HeaderRow.Cells.Add(HeaderCell);

        //Adding Head Office Credit Column
        HeaderCell = new TableCell();
        HeaderCell.Text = "Credit";
        HeaderCell.HorizontalAlign = HorizontalAlign.Center;
        HeaderCell.ColumnSpan = 2;
        HeaderCell.CssClass = "HeaderStyle";
        HeaderRow.Cells.Add(HeaderCell);

        //Adding Branch Office Debit Column
        HeaderCell = new TableCell();
        HeaderCell.Text = "Debit";
        HeaderCell.HorizontalAlign = HorizontalAlign.Center;
        HeaderCell.ColumnSpan = 2;
        HeaderCell.CssClass = "HeaderStyle";
        HeaderRow.Cells.Add(HeaderCell);

        //Adding Branch Office Credit Column
        HeaderCell = new TableCell();
        HeaderCell.Text = "Credit";
        HeaderCell.HorizontalAlign = HorizontalAlign.Center;
        HeaderCell.ColumnSpan = 2;
        HeaderCell.CssClass = "HeaderStyle";
        HeaderRow.Cells.Add(HeaderCell);

        ProductGrid.Controls[0].Controls.AddAt(1, HeaderRow);
    }
}

Here are the outputs of our example:

Three row header in GridView



43 Responses to “How to create multiple row header and merge it with other columns in GridView”

  • Anonymous says:
    19 February 2012 at 01:56

    Thank you so much... I struggled for hours to figure out how to create the multiple row header. Everything on the web had something similar but not what I wanted. Great code!

  • Anonymous says:
    28 February 2012 at 10:28

    Is this multi-row header sort-able?

  • Thirumalai M says:
    28 February 2012 at 13:16

    Hi, Currently the code is not enabled for multi-row header be sortable. Because the headers are created manually, we have to code for sorting.

  • Anonymous says:
    20 June 2012 at 12:06

    I am populating gridview in dropdown selectedindex change event.and creating extra rows like in ur example above.Next time when dropdwon value is change,then gridview has some extra cells(previous+newly created)which spoil the format of gridview.
    how to clear everything when dropdown value is change ?
    Has any one experience this ?

  • Thirumalai M says:
    20 June 2012 at 13:04

    Hi,
    I did not comeacross such issues. You can send me your sample code to me and I will try checking and give the solution.

  • Anonymous says:
    22 June 2012 at 17:32

    Hi Thiru,
    Problem is solved.In fact no extra code.For some reason,i wrote CreateCell Code in RowDataBound event.So that part was not rendering.Writing back that code in row_created event solved the problem.Now everything is rendered in excel.

  • Anonymous says:
    22 June 2012 at 17:36

    Hi Thiru,
    New problem !
    This is extension of above discussion.
    There is one logo right above gridview in the center.Image also get exported to excel.But it appear in left most part of excel.I want it appear in center in excel.
    How do i position the image in excel ?
    Any idea ?
    Thanks

  • Thirumalai M says:
    24 June 2012 at 23:25

    Hi, I did not tried yet images while exporting in this way. I hope you can keep the css style sheet in the html script itself and try centering the image and see the result.

    If you still need help, pls send me some code to verify and let you know.

    Additionally, you can verify the following url -
    http://www.dotnettwitter.com/2011/10/exporting-data-to-excel-sheet-with.html

  • Anonymous says:
    25 June 2012 at 14:34

    Hi,
    I am using rendering method to export.
    using normal css and even keeping them in html script is not working.

    Any other method.I don't want to change the export method.

  • Thirumalai M says:
    27 June 2012 at 22:20

    Hi, If the css file is a separate file I hope it could be an issue. So you use the styles inside the form itself. If possible provide the styles in the html script itself instead of defining a class and mentioning the class name.

    As the html script is separate and not refering the css file, it wont export the styles such as text-align:center etc.,

    Try this method and let me know if any issue.

  • Anonymous says:
    12 July 2012 at 15:43

    i am using sql server 2000 database and i want to use this merge concept on that data can you provide code for sql server database value not xml database value for the same example

  • Thirumalai M says:
    12 July 2012 at 16:01

    Hi,

    There wont be more changes in the code for doing with SQL Server database instead of XML. You just have to bind the data with dataset or datareader. So do the following

    1. Remove the XML file from the project and asp:XmlDataSource control from the page.
    2. Follow any of the post in the same blog which gets the data from the database and bind to the grid view. For Example see the below url
    http://www.dotnettwitter.com/2012/03/formula-fields-in-grid-view-part-1.html

    in that the first example (Getting Started) provides code for getting records from Northwind database and bind to the GridView.
    3. Rest of the code are same as defined in this post.

    Let me know if you still need any help.

  • Anonymous says:
    13 September 2012 at 20:12

    Great job! Thanks!

  • Unknown says:
    22 September 2012 at 05:57

    Hi I am running into an issue with the postback basically the text boxes seem to lose thier values on postback when I add the multiple row header feature. Pls help !!

  • Thirumalai M says:
    22 September 2012 at 22:03

    Hi, The issue with textbox might not be because of multiple roe header. I did not encounter this type of issue with my projects.

    Can you pls explain where the textbox present and is it created by dynamically in the client side? If you can provide me a sampel code, I can look at the issue and get back to you.

  • Anonymous says:
    4 January 2013 at 17:49

    ty so much

  • Anonymous says:
    2 March 2013 at 17:48

    Thank you so much

  • Srikanth says:
    5 April 2013 at 09:06

    How code these multiple row header to sort-able? Anybody have code for this?

  • Thirumalai M says:
    8 April 2013 at 15:15

    Hi Srikanth,

    You need to you custom sorting only. You can check the following post, for some idea.

    http://www.dotnettwitter.com/2011/05/database-pagination-in-gridview-using_08.html
    http://www.dotnettwitter.com/2011/05/database-pagination-in-gridview-using.html

  • sanju says:
    31 July 2013 at 18:25

    Could I get help to achieve same like that but I need a datafield instead of "Revenue" header text. Means instead of header text I need to show the text that I retrieved from DB

  • Thirumalai M says:
    1 August 2013 at 00:24

    You can directly access the header cells by accessing rows[0], rows[1] and loop the cells. You can set the values in any event, where you have the values ready.

  • Rama krishna says:
    28 August 2013 at 15:44

    hi how to decrease the height of gridview header

    please share your information

  • Anonymous says:
    29 August 2013 at 09:09

    hi what to take for template field instead of databound? please can you help me out.

  • Anonymous says:
    20 September 2013 at 23:50

    Fantastic piece of coding! Thank you for the example! I'll be using it soon!

  • Unknown says:
    6 November 2013 at 18:34

    Hi Thiru,
    Its a very good solution for adding multiple headers. But I got messes up with accessing dynamically created column's header text in rowdatabound event. I need the newly added column header text. Through code behind am able to get only the main header but not the one I created.
    Can you please help me out in fixing this.

    Regards,
    Rajashekar

  • www.vaskrishna.com says:
    18 December 2013 at 10:47

    It is very informative...Can any one please suggest me how to split abov Gridview based on Year ...

  • Ravi Kumar says:
    6 January 2014 at 13:02

    nice 1. I have found another example to Merge GridView Columns/Cells. please visit http://www.etechpulse.com/2013/07/c-merging-gridview-header-columnscells.html

  • Anonymous says:
    12 February 2014 at 14:47

    it was very helpful thank you

  • eunp says:
    3 June 2014 at 13:56

    Thanks so much !! my problem has been solved

  • Anonymous says:
    30 July 2014 at 12:44

    Thanks so much! My propblem has been solved. It take me long time.

  • Anonymous says:
    5 September 2014 at 17:41

    How to take this gridview to a pdf without changing the format of the gridview

  • Unknown says:
    28 October 2014 at 15:14

    Can anyone help in exporting the above gridview with same headers to excel

  • Gayatri says:
    29 October 2014 at 09:28

    Thank you So Much ...My propblem has been solved.

  • Unknown says:
    28 March 2015 at 14:01

    ThanQ Sir...

  • Anonymous says:
    25 May 2015 at 13:51

    Simple and Clean Code.......Thank You

  • Anonymous says:
    25 July 2015 at 13:37

    I am trying to run the same as provided by you, but my gridview header is being created twice. Not able to understand what might be the issue.

  • tulsihalwai says:
    6 January 2016 at 11:56

    It Helped

  • Unknown says:
    12 January 2016 at 16:23

    hi

    how can i bind grid-view and multiple row data show in label using asp.net

  • Msi sulthan says:
    5 March 2016 at 11:46

    super

  • Ranjith says:
    17 March 2016 at 15:55

    Hello thanks the example its good one, can we do the same for WPF Application ?

  • Thirumalai M says:
    18 March 2016 at 14:42

    Sorry Ranjith. I have limited experience on WPF.

  • Anonymous says:
    30 September 2016 at 01:05

    Good afternoon, can you help me?

    How do I export a griview with multiple headers to Excel?

    Thanks

  • Laxminarayan Mishra says:
    15 November 2019 at 14:28

    Hello Thank you so much, i tried so many different things but finally your approach solves my problem.

Post a Comment