Here I have created sample that will help you out.
HTML
<div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("[src*=minus]").each(function () {
$(this).closest("tr").after("<tr><td></td><td colspan = '999'>" + $(this).next().html() + "</td></tr>");
$(this).next().remove()
});
});
</script>
<asp:GridView ID="gvCustomers" runat="server" AutoGenerateColumns="false" CssClass="Grid"
DataKeyNames="CustomerID">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="imgShow" runat="server" OnClick="Show_Hide_ChildGrid" ImageUrl="~/images/plus.png"
CommandArgument="Show" />
<asp:Panel ID="pnlOrders" runat="server" Visible="false" Style="position: relative">
<asp:GridView ID="gvOrders" runat="server" AutoGenerateColumns="false" PageSize="5"
AllowPaging="true" OnPageIndexChanging="OnChildGrid_PageIndexChanging" CssClass="ChildGrid">
<Columns>
<asp:BoundField ItemStyle-Width="150px" DataField="OrderId" HeaderText="Order Id" />
<asp:BoundField ItemStyle-Width="150px" DataField="OrderDate" HeaderText="Date" />
</Columns>
</asp:GridView>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField ItemStyle-Width="150px" DataField="ContactName" HeaderText="Contact Name" />
<asp:BoundField ItemStyle-Width="150px" DataField="City" HeaderText="City" />
</Columns>
</asp:GridView>
</div>
C#
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
gvCustomers.DataSource = GetData("select top 10 * from Customers");
gvCustomers.DataBind();
}
}
private static DataTable GetData(string query)
{
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = query;
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataSet ds = new DataSet())
{
DataTable dt = new DataTable();
sda.Fill(dt);
return dt;
}
}
}
}
}
private void HideAllpanels(int index)
{
foreach (GridViewRow row in gvCustomers.Rows)
{
if (row.RowIndex != index)
{
ImageButton imgShowHide = (ImageButton)row.FindControl("imgShow");
imgShowHide.ImageUrl = "~/images/plus.png";
imgShowHide.CommandArgument = "Show";
row.FindControl("pnlOrders").Visible = false;
}
}
}
protected void Show_Hide_ChildGrid(object sender, EventArgs e)
{
ImageButton imgShowHide = (sender as ImageButton);
GridViewRow row = (imgShowHide.NamingContainer as GridViewRow);
HideAllpanels(row.RowIndex);
if (imgShowHide.CommandArgument == "Show")
{
row.FindControl("pnlOrders").Visible = true;
imgShowHide.CommandArgument = "Hide";
imgShowHide.ImageUrl = "~/images/minus.png";
string customerId = gvCustomers.DataKeys[row.RowIndex].Value.ToString();
GridView gvOrders = row.FindControl("gvOrders") as GridView; gvOrders.ToolTip = customerId;
gvOrders.DataSource = GetData(string.Format("select * from Orders where CustomerId='{0}'", customerId));
gvOrders.DataBind();
}
else
{
row.FindControl("pnlOrders").Visible = false;
imgShowHide.CommandArgument = "Show";
imgShowHide.ImageUrl = "~/images/plus.png";
}
}
private void BindOrders(string customerId, GridView gvOrders)
{
gvOrders.ToolTip = customerId;
gvOrders.DataSource = GetData(string.Format("select * from Orders where CustomerId='{0}'", customerId));
gvOrders.DataBind();
}
protected void OnChildGrid_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView gvOrders = (sender as GridView);
gvOrders.PageIndex = e.NewPageIndex;
BindOrders(gvOrders.ToolTip, gvOrders);
}
VB
Protected Sub Page_Load(sender As Object, e As EventArgs)
If Not IsPostBack Then
gvCustomers.DataSource = GetData("select top 10 * from Customers")
gvCustomers.DataBind()
End If
End Sub
Private Shared Function GetData(query As String) As DataTable
Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
Using con As New SqlConnection(constr)
Using cmd As New SqlCommand()
cmd.CommandText = query
Using sda As New SqlDataAdapter()
cmd.Connection = con
sda.SelectCommand = cmd
Using ds As New DataSet()
Dim dt As New DataTable()
sda.Fill(dt)
Return dt
End Using
End Using
End Using
End Using
End Function
Private Sub HideAllpanels(index As Integer)
For Each row As GridViewRow In gvCustomers.Rows
If row.RowIndex <> index Then
Dim imgShowHide As ImageButton = DirectCast(row.FindControl("imgShow"), ImageButton)
imgShowHide.ImageUrl = "~/images/plus.png"
imgShowHide.CommandArgument = "Show"
row.FindControl("pnlOrders").Visible = False
End If
Next
End Sub
Protected Sub Show_Hide_ChildGrid(sender As Object, e As EventArgs)
Dim imgShowHide As ImageButton = TryCast(sender, ImageButton)
Dim row As GridViewRow = TryCast(imgShowHide.NamingContainer, GridViewRow)
HideAllpanels(row.RowIndex)
If imgShowHide.CommandArgument = "Show" Then
row.FindControl("pnlOrders").Visible = True
imgShowHide.CommandArgument = "Hide"
imgShowHide.ImageUrl = "~/images/minus.png"
Dim customerId As String = gvCustomers.DataKeys(row.RowIndex).Value.ToString()
Dim gvOrders As GridView = TryCast(row.FindControl("gvOrders"), GridView)
gvOrders.ToolTip = customerId
gvOrders.DataSource = GetData(String.Format("select * from Orders where CustomerId='{0}'", customerId))
gvOrders.DataBind()
Else
row.FindControl("pnlOrders").Visible = False
imgShowHide.CommandArgument = "Show"
imgShowHide.ImageUrl = "~/images/plus.png"
End If
End Sub
Private Sub BindOrders(customerId As String, gvOrders As GridView)
gvOrders.ToolTip = customerId
gvOrders.DataSource = GetData(String.Format("select * from Orders where CustomerId='{0}'", customerId))
gvOrders.DataBind()
End Sub
Protected Sub OnChildGrid_PageIndexChanging(sender As Object, e As GridViewPageEventArgs)
Dim gvOrders As GridView = TryCast(sender, GridView)
gvOrders.PageIndex = e.NewPageIndex
BindOrders(gvOrders.ToolTip, gvOrders)
End Sub
Screenshot
