I was wondering if anybody here could help guide me in the right direction for creating a gridview that contains rows that collapse with another gridview inside. I know we're not supposed to actually ask for codes but I haven't written one yet, I'm just asking for pointers :)

I'm trying to make it look like the jpg i attached.

Any help would be appreciated. Thanks! :)

Attachments nestedGridview.JPG 32.52 KB
8 Years
Discussion Span
Last Post by nixx

So far, this is what I've got:

<%@ Page Title="" Language="C#" MasterPageFile="~/MASTERPAGES/master.master" AutoEventWireup="true" CodeFile="nestedGridviewTest.aspx.cs" Inherits="PAGES_nestedGridviewTest" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <asp:GridView ID="gvGroup" runat="server" AutoGenerateColumns="false" CssClass="gv gvGroupList"
    AllowPaging="false" AllowSorting="false" OnRowCommand="gvGroup_OnRowCommand" DataKeyNames="ID">
                    <asp:CheckBox runat="server" ID="chkAll" AutoPostBack="true" CssClass="DisableValidation"/>
                    <asp:CheckBox ID="chkDelete" runat="server" name="chkDel"/>
                <ItemStyle CssClass="gvCellCenter gvSelect" />                    
                <HeaderStyle CssClass="gvHeader gvSelect" />
            <asp:TemplateField HeaderText="Group">
                    <asp:Label ID="lblIndicator" runat="server" Text="0" Visible="false" />
                    <asp:LinkButton ID="lnkName" runat="server" CommandName="Skills" Text='<%# bind("Name") %>' CommandArgument='<%# DataBinder.Eval(Container, "RowIndex") %>' />    
                <ItemStyle CssClass="gvCell" />
            <asp:BoundField HtmlEncode="false" DataField="Description" HeaderText="Description" SortExpression="Description">
                <ItemStyle CssClass="gvCell" />
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using Test.Data;
using Test.Business;
using System.Linq.Expressions;
using Test.Common;
using Test.Security;

public partial class PAGES_nestedGridviewTest : System.Web.UI.Page
    #region Properties
    private int SelectedIndex
        get { return (int)ViewState["RowIndex"]; }
        set { ViewState["RowIndex"] = value; }

    #region Events
    protected void Page_Load(object sender, EventArgs e)
        if (!Page.IsPostBack)

    protected void gvGroup_OnRowCommand(object sender, GridViewCommandEventArgs e)
        SelectedIndex = int.Parse(e.CommandArgument.ToString());
        Label lblIndicator = (Label)gvGroup.Rows[SelectedIndex].FindControl("lblIndicator");
        int LastCellPosition = gvGroup.Rows[SelectedIndex].Cells.Count - 1;
        int NewCellPosition = gvGroup.Rows[SelectedIndex].Cells.Count;

        if (e.CommandName == "Members")
            if (lblIndicator.Text == "0")
                int GroupID = Convert.ToInt16(gvGroup.DataKeys[SelectedIndex].Value);
                List<Member> MemberList = GroupBL.RetrieveMemberByGroup(GroupID);

                //create a new gridview
                GridView newGV = new GridView();
                newGV.AutoGenerateColumns = false;
                newGV.AllowPaging = false;
                newGV.AllowSorting = false;
                newGV.CssClass = "gv";
                newGV.Width = Unit.Percentage(100);
                newGV.ID = "gvGroup_" + GroupID + "_Members";

                //define the columns of the nested gridview
                addColumns(newGV, "Name", "Name", HorizontalAlign.Left);
                addColumns(newGV, "Description", "Description", HorizontalAlign.Left);
                addColumns(newGV, "Comments", "Comments", HorizontalAlign.Left);

                //bind the nested gridview
                newGV.DataSource = generateTable(MemberList);

                //create the remove button
                Button btnRemoveMembers = new Button();
                btnRemoveMembers.ID = "btnRemoveMembers";
                btnRemoveMembers.Text = "Remove";

                //create a panel/div below the selected row
                Panel UP = new Panel();
                UP.BorderStyle = BorderStyle.None;
                UP.BackColor = System.Drawing.Color.White;
                UP.Width = gvGroup.Width;
                UP.ID = "uniquename" + SelectedIndex;
                UP.CssClass = "panelChild";

                //add the controls to the panel/div
                UP.Visible = true;

                //Render New GridView to DIV
                System.IO.StringWriter sw = new System.IO.StringWriter();
                System.Web.UI.HtmlTextWriter htw = new System.Web.UI.HtmlTextWriter(sw);
                string DivBody = sw.ToString();

                if (SelectedIndex % 2 == 0)
                    gvGroup.Rows[SelectedIndex].Cells[LastCellPosition].Text += "<tr><td  bgcolor='white' colspan='" + NewCellPosition + "'>" + DivBody;
                    gvGroup.Rows[SelectedIndex].Cells[LastCellPosition].Text += "<tr><td bgcolor='lightgrey' colspan='" + NewCellPosition + "'>" + DivBody;

                lblIndicator.Text = "1";

                LastCellPosition = gvGroup.Rows[SelectedIndex].Cells.Count - 1;
                gvGroup.Rows[SelectedIndex].Cells[LastCellPosition].Text = "1";
                lblIndicator.Text = "0";

    #region Private Methods
    private void populateGridView()
        gvGroup.DataSource = GroupBL.GetGroupList();

    private void addColumns(GridView newGV, string DataField, string HeaderText, HorizontalAlign Align)
        BoundField bF = new BoundField();
        bF.HeaderText = HeaderText;
        bF.DataField = DataField;
        bF.ItemStyle.HorizontalAlign = Align;
        bF.ItemStyle.CssClass = "gvCell";

    private void addCheckBoxes(GridView newGV)
        CheckBox cb = new CheckBox();
        TemplateField tf = new TemplateField();
        tf.ItemTemplate =
        tf.ItemStyle.CssClass = "gvCheck";

    private static DataTable generateTable(List<Member> MemberList)
        DataTable dt = new DataTable();

        //define the columns of the table
        dt.Columns.Add(new DataColumn("ID", typeof(int)));
        dt.Columns.Add(new DataColumn("Name", typeof(string)));
        dt.Columns.Add(new DataColumn("Description", typeof(string)));
        dt.Columns.Add(new DataColumn("Comments", typeof(string)));

        foreach (Member s in MemberList)
            //create a new row
            DataRow dr = dt.NewRow();

            //enter row details
            dr["ID"] = s.ID;
            dr["Name"] = s.Name;
            dr["Description"] = s.Description;
            dr["Comments"] = s.Comments;

            //add the row to the datatable

        return dt;

I have no idea how to add a templatefield to the gridview from the code. I need it for the checkboxes.

Any help would be appreciated. Thanks!


You can follow the below steps:
1. Add a template column within the master gridview.
2. Add a collapse image first like <img src="Image/Expand.jpg" onclick="ChildBlock(this,document.getElementById('<%#Eval("ChildID") %>'));" /> which will show hide child details based on user selection by a javascript method.
3. Add a div & give the id=child data id within the template column. Like <div id='<%#Eval("ChildID") %>' style="display:none"> . After that add the child gridview.
4. The childblick javascript method like below:

function ChildBlock(img,obj)

5. Ok now design is complete. Bind master grid into the page load event & in the RowDataBound method bind child grid in the below way:

if (e.Row.RowType == DataControlRowType.DataRow)
DataTable dtProducts = GetProducts(Convert.ToUInt64(((DataRowView)e.Row.DataItem)["ID"]));
((GridView)e.Row.FindControl("gvChild")).DataSource = dtProducts;

Edited by mail2saion: n/a

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.