Click here to Skip to main content
15,886,422 members
Articles / Web Development / HTML

Nested GridView in ASP.NET using C#

Rate me:
Please Sign up or sign in to vote.
4.95/5 (13 votes)
27 Nov 2013CPOL2 min read 149.9K   6.9K   27   11
This example shows you how to create a nested GridView.

Introduction:

This example shows you how to create a nested GridView, i.e. a GridView under another GridView, using very little jQuery code. 

Nested GridView

Background

I’m using the Northwind database here.

Quick Start

In Master GridView I’ll show you the Customer’s details i.e., ContactName and City from ‘Customer’ table. Then in the Child GridView I’ll show you Order details of corresponding Customers i.e. OrderID and OrderDate.

Creating Main GridView:

HTML
<asp:GridView ID="grdViewCustomers" runat="server" 
          AutoGenerateColumns="false" DataKeyNames="CustomerID"
          OnRowDataBound="grdViewCustomers_OnRowDataBound" CssClass="Grid">
    <columns>
        <asp:BoundField ItemStyle-Width="150px" DataField="ContactName" HeaderText="Contact Name" />
        <asp:BoundField ItemStyle-Width="150px" DataField="City" HeaderText="City" />
    </columns>

So, now it shows only two column i.e. ContactName and City. Now, I’ll insert ‘plus sign image’ to the First Column of every row. As because, when I’ll click this ‘plus sign image’ then the Child GridView will displayed and the ‘plus sign image’ will be the ‘minus sign image’. And when I’ll click the ‘minus sign image’ the Child GridView will remove from our sight and ‘minus sign image’ becomes the ‘plus sign image’ like toggle. So, I’ve to take an ItemTemplate within a TemplateField inside the Columns at first position. Let see:

HTML
<asp:GridView ID="grdViewCustomers" runat="server" AutoGenerateColumns="false" DataKeyNames="CustomerID"
    OnRowDataBound="grdViewCustomers_OnRowDataBound" CssClass="Grid">
    <columns>
        <asp:TemplateField ItemStyle-Width="20px">
            <itemtemplate>
                <a href="java<!-- no -->script:divexpandcollapse('div<%# Eval(">
                    <img id="imgdiv<%# Eval(" alt="Details" src="images/plus.png" />
                </a>
        
                <asp:BoundField ItemStyle-Width="150px" 
                  DataField="ContactName" HeaderText="Contact Name" />
                <asp:BoundField ItemStyle-Width="150px" 
                  DataField="City" HeaderText="City" />
            </itemtemplate>
    </columns>

Now, you see that I’ve linked a JavaScript function to the ‘plus sign image’ which does the all functionality what I’ve told above against the Click event of the ‘plus sign image’. This JavaScript function takes the Div name in which the Child GridView exists. There will be one Child GridView for each row of the Master GridView. So, the Div id must be different. That’s why I concatenate Div id with CustomerID and there will one ‘plus sign image’ for each row of the Master GridView, so I also concatenate the img id with CustomerID. Now lets add the Div just after the link of the ‘plus sign image’ and implement Child GridView under that Div:

HTML
<asp:GridView ID="grdViewCustomers" runat="server" 
           AutoGenerateColumns="false" DataKeyNames="CustomerID"
    OnRowDataBound="grdViewCustomers_OnRowDataBound" CssClass="Grid">
    <columns>
        <asp:TemplateField ItemStyle-Width="20px">
            <itemtemplate>
                <a href="java<!-- no -->script:divexpandcollapse('div<%# Eval(">
                    <img id="imgdiv<%# Eval(" alt="Details" src="images/plus.png" />
                </a>
                <div id="div<%# Eval(" style="display: none;">
                    <asp:GridView ID="grdViewOrdersOfCustomer" 
                            runat="server" AutoGenerateColumns="false"
                            DataKeyNames="CustomerID" CssClass="ChildGrid">
                        <columns>
                            <asp:BoundField ItemStyle-Width="150px" 
                              DataField="OrderID" HeaderText="Order ID" />
                            <asp:BoundField ItemStyle-Width="150px" 
                              DataField="OrderDate" HeaderText="Order Date" />
                        </columns>
                    
                </div>
            </itemtemplate>
        
        <asp:BoundField ItemStyle-Width="150px" 
          DataField="ContactName" HeaderText="Contact Name" />
        <asp:BoundField ItemStyle-Width="150px" 
          DataField="City" HeaderText="City" />
    </columns>

Lets see the little JQuery which checks whether the ‘plus sign image’ source contains the path of the ‘plus sign’ image or ‘minus sign’ image and do said functionality accordingly:

JavaScript
function divexpandcollapse(divname) {
    var img = "img" + divname;
    if ($("#" + img).attr("src") == "images/plus.png") {
        $("#" + img)
    .closest("tr")
    .after("" + $("#" + divname)
    .html() + "")
        $("#" + img).attr("src", "images/minus.png");
    } else {
        $("#" + img).closest("tr").next().remove();
        $("#" + img).attr("src", "images/plus.png");
    }
}

Now the client side part is over. The main part is how you fill the Child GridView? Don’t worry, there is an event which is triggered when there is one container control within the row of the GridView. The event is OnRowDataBound. And I’ve already added this event to the Master GridView properties and the name of event handler is: grdViewCustomers_OnRowDataBound. And we also fill the Master GridView in the Page_Load() event. So lets implement:

C#
protected void Page_Load(object sender, EventArgs e)
{
    grdViewCustomers.DataSource = 
      SelectData("SELECT top 3 CustomerID, ContactName, City FROM Customers");
    grdViewCustomers.DataBind();
}

private DataTable SelectData(string sqlQuery)
{
    string connectionString = 
      System.Web.Configuration.WebConfigurationManager.ConnectionStrings[
      "SQLServerConnectionString"].ConnectionString;
    using (SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlQuery, connectionString))
    {
        DataTable dt = new DataTable("Customers");
        sqlDataAdapter.Fill(dt);
        return dt;
    }
}

protected void grdViewCustomers_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        string customerID = grdViewCustomers.DataKeys[e.Row.RowIndex].Value.ToString();
        GridView grdViewOrdersOfCustomer = (GridView)e.Row.FindControl("grdViewOrdersOfCustomer");
        grdViewOrdersOfCustomer.DataSource = SelectData(
          "SELECT top 3 CustomerID, OrderID, OrderDate FROM Orders WHERE CustomerID='" + 
          customerID + "'");
        grdViewOrdersOfCustomer.DataBind();
    }
}

It's done.

History

This is the first release of this Article. In the next release I’ll show you how you add a button in nested GridView and how the whole thing can be done using AJAX. Thank you.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer National Informatics Centre (NIC)
India India
Hello! Myself Debopam Pal. I've completed my MCA degree from West Bengal University of Technology at 2013. I'm from India. I’ve started to work with MS Technologies in 2013 specially in C# 4.0, ASP.NET 4.0. I've also worked in PHP 5. Now I work in JAVA/J2EE, Struts2. Currently I'm involved in a e-Governance Project since Jan, 2014. In my leisure time I write Blog, Articles as I think that every developer should contribute something otherwise resource will be finished one day. Thank you for your time.

Visit: Linkedin Profile | Facebook Profile | Google+ Profile | CodeProject Profile

Comments and Discussions

 
QuestionCollapse all/expand all Pin
Member 45336262-Sep-15 8:59
Member 45336262-Sep-15 8:59 
QuestionPaging implemment in child gridview Pin
rrx6666-May-15 10:19
rrx6666-May-15 10:19 
QuestionBuild Error - The name 'grdViewCustomers' does not exist in the current context. Pin
WizardofWoz25-Apr-15 2:34
WizardofWoz25-Apr-15 2:34 
QuestionClarification for the solution you provided Pin
Santhosh Chitloor26-Feb-15 20:09
professionalSanthosh Chitloor26-Feb-15 20:09 
QuestionNested gridview with Asp.Net Chart no image display in Chrome. Pin
Karamathulla17-Jun-14 20:36
Karamathulla17-Jun-14 20:36 
Questionjavascript not working in this code. Pin
ANUJAKUMARI15-Jun-14 21:34
ANUJAKUMARI15-Jun-14 21:34 
Questionnested grid view can we provide save or update option in child gridview. Pin
Member 1021767816-Jan-14 17:34
Member 1021767816-Jan-14 17:34 
QuestionRefreshing Pin
Member 1037323418-Dec-13 12:03
Member 1037323418-Dec-13 12:03 
QuestionNeed Help Pin
madhukar anand3-Dec-13 22:48
madhukar anand3-Dec-13 22:48 
QuestionNo Code in zip file Pin
Theo Bohonk23-Nov-13 9:34
professionalTheo Bohonk23-Nov-13 9:34 
AnswerRe: No Code in zip file Pin
Debopam Pal24-Nov-13 1:12
professionalDebopam Pal24-Nov-13 1:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.