As I said in my last post, I would write about the Check/ Uncheck checkboxes of Treeview based on database value, and I think it’s very easy, so skipping that part and here I am going to write about Nested Gridview will look like the below image:
Rather than displaying Nested Gridview in the same row, we’ll display it in the below row, which gives the user a proper understanding of the data. Let’s see, How can it be done?
First, I am using Northwind Database that comes with SQL Server; if you do not have it, you can download it.
Here’s the HTML Source Code for Parent GridView; change it according to the language C# or VB and your requirement:
<asp:GridView ID="gvOrders" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" DataKeyNames="OrderID" CellPadding="4" ForeColor="#333333">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblSign" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="OrderID" HeaderText="OrderID" InsertVisible="False" ReadOnly="True" SortExpression="OrderID" />
<asp:BoundField DataField="CustomerID" HeaderText="CustomerID" SortExpression="CustomerID" />
<asp:BoundField DataField="EmployeeID" HeaderText="EmployeeID" SortExpression="EmployeeID" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
<asp:BoundField DataField="Region" HeaderText="Region" SortExpression="Region" />
<asp:BoundField DataField="Postal" HeaderText="Postal" SortExpression="Postal" />
<asp:BoundField DataField="Country" HeaderText="Country" SortExpression="Country" />
<asp:TemplateField>
<ItemTemplate>
<tr>
<td colspan="100%">
<div id="div<%#Eval("OrderID") %>" style="display: none; position: relative;">
</div>
</td>
</tr>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<EditRowStyle BackColor="#999999" />
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
</asp:GridView>
In the above code, we’ve inserted <tr> and <td> and <div> tag that is highlighted by Yellow background colour. Gridview is rendered as an HTML table, and GridView rows will be rendered as <tr>. Cells will be as <td> so that we are explicitly inserting those tags to show our child Gridview exactly below the corresponding Gridview Row rather than in the last column of Parent Gridview.
SQL DataSource Code for Parent GridView :
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
SelectCommand="SELECT TOP (10) OrderID, CustomerID, EmployeeID, ShipName as Name,
ShipAddress as Address, ShipCity as City, ShipRegion as Region, ShipPostalCode as Postal,
ShipCountry as Country FROM Orders"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>">
</asp:SqlDataSource>
Child GridView Code :
<asp:GridView ID="gvDetails" runat="server" CellPadding="4" ForeColor="#333333" GridLines="Both"
DataSourceID="SqlDataSource2" Style="position: relative" AutoGenerateColumns="False">
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<EditRowStyle BackColor="#999999" />
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" SortExpression="UnitPrice" />
<asp:BoundField DataField="Quantity" HeaderText="Quantity" SortExpression="Quantity" />
<asp:BoundField DataField="Discount" HeaderText="Discount" SortExpression="Discount" />
<asp:BoundField DataField="CompanyName" HeaderText="CompanyName" SortExpression="CompanyName" />
</Columns>
</asp:GridView>
SQL DataSource Code for Child GridView
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT C.CompanyName, OD.UnitPrice, OD.Quantity, OD.Discount, E.FirstName, E.LastName, OD.OrderID, C.CustomerID, E.EmployeeID FROM dbo.[Order Details] AS OD INNER JOIN
dbo.Orders AS O ON OD.OrderID = O.OrderID INNER JOIN
dbo.Customers AS C ON O.CustomerID = C.CustomerID INNER JOIN
dbo.Employees AS E ON O.EmployeeID = E.EmployeeID AND O.OrderID LIKE @OrderId AND C.CustomerID = @CustomerID AND
E.EmployeeID = @EmployeeId">
<SelectParameters>
<asp:Parameter Name="OrderId" />
<asp:Parameter Name="CustomerId" />
<asp:Parameter Name="EmployeeId" />
</SelectParameters>
</asp:SqlDataSource>
We’ll supply OrderId, CustomerID, and EmployeeID to SQL DataSource of ChildGridView in RowDataBound of Parent GridView.
Parent GridView Event Handlers
C#
protected void gvOrders_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header || e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[1].Visible = false;
e.Row.Cells[2].Visible = false;
e.Row.Cells[3].Visible = false;
}
}
protected void gvOrders_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
e.Row.Cells[1].Visible = false;
e.Row.Cells[2].Visible = false;
e.Row.Cells[3].Visible = false;
}
if (e.Row.RowType == DataControlRowType.DataRow)
{
SqlDataSource s = (SqlDataSource)e.Row.FindControl("SqlDataSource2");
s.SelectParameters[0].DefaultValue= e.Row.Cells[1].Text;
s.SelectParameters[1].DefaultValue = e.Row.Cells[2].Text;
s.SelectParameters[2].DefaultValue = e.Row.Cells[3].Text;
((Label)e.Row.FindControl("lblSign")).Text = "+";
((Label)e.Row.FindControl("lblSign")).Attributes["onclick"] = "HideShowDiv('div" + e.Row.Cells[1].Text + "', '" + ((Label)e.Row.FindControl("lblSign")) .ClientID + "');";
e.Row.Cells[0].Attributes["onmouseover"] = "this.style.cursor='pointer'";
e.Row.Cells[0].Attributes["onmouseout"] = "this.style.cursor='pointer'";
}
}
VB
Protected Sub gvOrders_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvOrders.RowCreated
If e.Row.RowType = DataControlRowType.Header Or e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Cells(1).Visible = False
e.Row.Cells(2).Visible = False
e.Row.Cells(3).Visible = False
End If
End Sub
Protected Sub gvOrders_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.Header Then
e.Row.Cells(1).Visible = False
e.Row.Cells(2).Visible = False
e.Row.Cells(3).Visible = False
End If
If e.Row.RowType = DataControlRowType.DataRow Then
Dim s As SqlDataSource = CType(e.Row.FindControl("SqlDataSource2"), SqlDataSource)
s.SelectParameters(0).DefaultValue= e.Row.Cells(1).Text
s.SelectParameters(1).DefaultValue = e.Row.Cells(2).Text
s.SelectParameters(2).DefaultValue = e.Row.Cells(3).Text
(CType(e.Row.FindControl("lblSign"), Label)).Text = "+"
(CType(e.Row.FindControl("lblSign"), Label)).Attributes("onclick") = "HideShowDiv('div" + e.Row.Cells(1).Text + "', '" + (CType(e.Row.FindControl("lblSign"), Label)) .ClientID + "');"
e.Row.Cells(0).Attributes("onmouseover") = "this.style.cursor='pointer'"
e.Row.Cells(0).Attributes("onmouseout") = "this.style.cursor='pointer'"
End If
End Sub
JavaScript
function HideShowDiv(DivId,LblSign)
{
var mydiv= document.getElementById(DivId);
var LblSign=document.getElementById(LblSign);
if(mydiv!=null && LblSign!=null)
{
if(mydiv.style.display!="block")
{
mydiv.style.display="block";
LblSign.innerHTML="-";
}
else
{
mydiv.style.display="none";
LblSign.innerHTML="+";
}
}
}
The above JavaScript function will Hide/ Show the div and change the Sign of the Parent Row on the expansion of the div and so on. I hope this helps!!
Next time I will write How to generate Child Gridview Dynamically.
Enjoy!
Leave a Reply