Nested GridView in ASP.NET
The GridView control is the successor to the DataGrid and extends it in a number of ways. In some situations we have to display data in a Master-Child manner. In the following article, you can see how to create a GridView control to display data in a Matser-Child way.
Database
In this article I have used Microsoft's Pubs database for sample data. You can download it free from the following link.
Download How to nested Gridview Control
A nested GridView refers to a GridView control that is nested within a grid row of a parent GridView control. This hierarchical structure allows for the presentation of more complex data relationships, where the parent GridView displays master data from one table, while the nested GridView displays related child data from another table.
In this particular program, the focus is on displaying master data from the Publisher table. Each row in the parent GridView represents a master record from the Publisher table. Within each row, a nested GridView is utilized to display child data from the Titles table, which is associated with the corresponding publisher.
By employing this nested GridView approach, the program enables the presentation of a comprehensive view of data, providing insights into the relationships between the Publisher and Titles tables. Users can access and analyze the child data within each publisher's row, enhancing their understanding of the overall dataset.
This hierarchical structure facilitates the display of a master-detail relationship, allowing users to drill down into the child data as needed. It provides a powerful mechanism for showcasing complex data relationships and delivering a more comprehensive and informative user experience.
Expand/Collapse
Here the Gridview show Master/Details in Expand/Collapse way. When you click on + symbol the Gridview expand the row and inside the row it display the child Gridview. Then the row display a - symbol and when you click on the - symbol the it collapse and show the master GridView only.
Here the program manage this expand/collapse using two images and it functioning with the support of a small jQuery function.
Default.aspx
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Gridview inside another Gridview</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
function shrinkandgrow(input) {
var displayIcon = "img" + input;
if ($("#" + displayIcon).attr("src") == "grow.png")
{
$("#" + displayIcon).closest("tr")
.after("<tr><td></td><td colspan = '100%'>" + $("#" + input)
.html() + "</td></tr>");
$("#" + displayIcon).attr("src", "shrink.png");
} else
{
$("#" + displayIcon).closest("tr").next().remove();
$("#" + displayIcon).attr("src", "grow.png");
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" DataKeyNames="pub_id"
OnRowDataBound="GridView1_OnRowDataBound" HeaderStyle-BackColor="#A52A2A" HeaderStyle-ForeColor="White" >
<Columns>
<asp:TemplateField ItemStyle-Width="20px">
<ItemTemplate>
<a href="JavaScript:shrinkandgrow('div<%# Eval("pub_id") %>');">
<img alt="Details" id="imgdiv<%# Eval("pub_id") %>" src="grow.png" />
</a>
<div id="div<%# Eval("pub_id") %>" style="display: none;">
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="false" DataKeyNames="pub_id"
HeaderStyle-BackColor="#FFA500" HeaderStyle-ForeColor="White">
<Columns>
<asp:BoundField ItemStyle-Width="150px" DataField="title" HeaderText="Title" />
<asp:BoundField ItemStyle-Width="100px" DataField="type" HeaderText="Category" />
<asp:BoundField ItemStyle-Width="100px" DataField="price" HeaderText="Price" />
</Columns>
</asp:GridView>
</div>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField ItemStyle-Width="150px" DataField="pub_name" HeaderText="Publisher" />
<asp:BoundField ItemStyle-Width="100px" DataField="state" HeaderText="State" />
<asp:BoundField ItemStyle-Width="100px" DataField="country" HeaderText="Country" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
C# Source Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
public partial class NestedGridView : System.Web.UI.Page
{
string connetionString = "Data Source=.;Initial Catalog=pubs;User ID=sa;Password=*****";
protected void Page_Load(object sender, EventArgs e)
{
string sql = "SELECT pub_id, pub_name,state,country FROM publishers";
GridView1.DataSource = getData(sql);
GridView1.DataBind();
}
protected void GridView1_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string pub_id = GridView1.DataKeys[e.Row.RowIndex].Value.ToString();
string sql = "SELECT pub_id, title, type,price FROM titles WHERE pub_id='" + pub_id + "'";
GridView pubTitle = (GridView)e.Row.FindControl("GridView2");
pubTitle.DataSource = getData(sql);
pubTitle.DataBind();
}
}
private DataTable getData(string sql)
{
SqlDataAdapter adapter = new SqlDataAdapter();
DataTable dTable = new DataTable();
SqlConnection connection = new SqlConnection(connetionString);
connection.Open();
SqlCommand command = new SqlCommand(sql, connection);
adapter.SelectCommand = command;
adapter.Fill(dTable);
adapter.Dispose();
command.Dispose();
connection.Close();
return dTable;
}
}
VB.Net Source Code
Imports System.Drawing
Imports System.Data.SqlClient
Imports System.Data
Partial Class _Default
Inherits System.Web.UI.Page
Dim connetionString As String = "Data Source=.;Initial Catalog=pubs;User ID=sa;Password=zen412"
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim sql As String = "SELECT pub_id, pub_name,state,country FROM publishers"
GridView1.DataSource = getData(sql)
GridView1.DataBind()
End Sub
Protected Sub GridView1_OnRowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim pub_id As String = GridView1.DataKeys(e.Row.RowIndex).Value.ToString()
Dim sql As String = (Convert.ToString("SELECT pub_id, title, type,price FROM titles WHERE pub_id='") & pub_id) + "'"
Dim pubTitle As GridView = DirectCast(e.Row.FindControl("GridView2"), GridView)
pubTitle.DataSource = getData(sql)
pubTitle.DataBind()
End If
End Sub
Private Function getData(ByVal sql As String) As DataTable
Dim adapter As New SqlDataAdapter()
Dim dTable As New DataTable()
Dim connection As New SqlConnection(connetionString)
connection.Open()
Dim command As New SqlCommand(sql, connection)
adapter.SelectCommand = command
adapter.Fill(dTable)
adapter.Dispose()
command.Dispose()
connection.Close()
Return dTable
End Function
End Class