Introduction and Background
There are several implementations available for nesting
GridViews on the internet. On MSDN, there is a set of code available, but that does not solve the problem of most developers. Just adding another
GridView in the template field of the parent GridView is not enough.
I'll start off quick from the beginning so that those developers who are new with this behavior of
GridView won’t have any issues achieving the end result.
GridView and add a Template File to the
GridView. You can achieve this by going into Edit Columns from GridView Tasks. Once this is done, Edit Template and Insert a
LinkButton with " + " as its
Text property. Make it X-Large and remove the Underline. Insert a child
GridView right next to the
These kinds of arrangements are usually required when you already have a relationship between two tables. Like in my example, there is a relationship between the Order Table and the Detail Table. I assume you have already created the
SqlDataSources for both
GridViews according to your requirements.
The important thing here is that, you must not assign any Source to the Parameter in the child GridView's
SqlDataSource. In other words, assign the source as "None" for the Child DataSource.
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:IVN_sysConnectionString %>"
SelectCommand="SELECT [order_no_fk], [item_name], [order_status], [description],
[quantity], [unit_price], [net_cost], [order_detail_no]
FROM [order_detail] WHERE ([order_no_fk] = @order_no_fk)" >
<asp:Parameter Name="order_no_fk" Type="String" />
Once you are done with it, return back to the parent
GridView and create an event handler for
protected void GridView1_RowDataBound(object sender,GridViewRowEventArgs e)
if (e.Row.RowType == DataControlRowType.DataRow)
SqlDataSource s = (SqlDataSource)e.Row.FindControl("SqlDataSource2");
s.SelectParameters.DefaultValue = e.Row.Cells.Text;
This is the part of code that is actually available at MSDN, most of you may already have gone through this but, I'll just explain it in a few simple words.
Our goal over here is to assign the parameter source value, the one earlier we declared as "None" in the
SqlDataSource of the child
GridView. For starters who have just seen this type of code for the first time, I think it will now be a little bit more meaningful.
Now, go back to the Template Field and create an event handler for the
LinkButton1_Click event. Before actually writing the event handler, you have to create an ASP
Panel inside the Template Field. Place the child
GridView in the newly created ASP
Panel. Note that the
LinkButton must remain outside the
Panel you have just added.
Visible property of the ASP
Panel equals "False".
protected void LinkButton1_Click(object sender, EventArgs e)
LinkButton l_btn = (LinkButton)sender;
GridViewRow gvr = (GridViewRow)l_btn.NamingContainer
Panel p1 = (Panel)gvr.FindControl("Panel1");
LinkButton lb1 = (LinkButton)gvr.FindControl("LinkButton1");
if (p1.Visible == false)
p1.Visible = true;
lb1.Text = "-";
else if (p1.Visible == true)
p1.Visible = false;
lb1.Text = "+";
GridView gv2 = (GridView)l_btn.FindControl("GridView2");
You can achieve your desired formatting just by adjusting the width of the ASP
Panel. It won't make a difference if your child
GridView has a greater width than the ASP
Finally, go to the parent
GridView and vertical align each row at the Top position. This way, you can see the parent's row entries when the child grid pops underneath it.
Whenever “+” is pressed, you experience a postback. You can simply use the AJAX
UpdatePanel to overcome this behavior. Just add the AJAX
UpdatePanel and simply place your parent
GridView inside the
UpdatePanel. That will give you the desired nested