Often we use nested GridView controls, so that individual rows in the master GridView can display a nested GridView in one of its columns. This is especially useful to show master/details relationships. However sometimes we might want to show the nested GridView only for the selected row. This post discusses one way to do it.
Prerequisites
Understanding of the GridView control.
Understanding of TemplateField class.
Understanding of SqlDataSource class.
If you are looking to understand how to create nested GridView controls, there is an excellent article on MSDN titled: Walkthrough: Creating a Nested GridView Control
Listed below is the source code for my aspx page. I've kept only the essential parts of the code:
1: <asp:SqlDataSource ID="masterDataSource" .../>
2: <asp:SqlDataSource ID="nestedDataSource" ... />
3: <asp:GridView ID="masterGrid" OnSelectedIndexChanged="masterGrid_SelectedIndexChanged" ...>
4: <Columns>
5: <asp:BoundField ... />
6: <asp:BoundField ... />
7: <asp:TemplateField>
8: <ItemTemplate>
9: <asp:GridView ID="nestedGrid" DataSourceID="nestedDataSource" Visible="false">
10: <Columns>
11: <asp:BoundField ... />
12: </Columns>
13: </asp:GridView>
14: </ItemTemplate>
15: </asp:TemplateField>
16: </Columns>
17: </asp:GridView>
Line 1: SqlDataSource called masterDataSource which will be used to populate the master GridView (masterGrid, line 3)
Line 2: SqlDataSource called nestedDataSource which will be used to populate the nested GridView (nestedGrid, line 9)
Line 3: Master GridView called masterGrid. Uses masterDataSource as the data source. Specifies masterGrid_SelectedIndexChanged as the method handler for SelectedIndexChanged event.
Line 9: Nested GridView called nestedGrid. Uses masterDataSource as the data source. Insert as a TemplateField.
Listed below is the source code for the masterGrid_SelectedIndexChanged event:
1: protected void masterGrid_SelectedIndexChanged(object sender, EventArgs e)
2: {
3: foreach (GridViewRow row in masterGrid.Rows)
4: {
5: row.FindControl("nestedGrid").Visible = false;
6: }
7: //Retrieve the data to be filled in the nestedGrid for the selected row
8: nestedDataSource.SelectParameters[0].DefaultValue = masterGrid.SelectedDataKey[0].ToString();
9: nestedDataSource.DataBind();
10: //Set the visibility of for the nestedGrid for the selected row
11: masterGrid.SelectedRow.FindControl("nestedGrid").Visible = true;
12: }
Line 3-6: I hide all the nestedGrid controls.
Line 11: For only the selected row I show the nestedGrid. It was as simple as that!.
Great Article! Very simple and easy to understand. However, I have a user who wants to have the ability to have all the nested grid values be visible at the click of a button. Any Suggestions?
ReplyDeleteCan you show an example of this in VB? I've used a code converter, but it says there is an error in the c# code.
ReplyDeleteGreat article was looking for something like this for a while.
ReplyDelete@Amar. The way you could do it in your situation would be to have a have code on a button to loop through all rows in the grid and set the nested grid to visible for every row. So it would do the opposite of the code in this article.
This comment has been removed by a blog administrator.
ReplyDeleteHi there, I know this is an old article but I was hoping any of you could help me.
ReplyDeleteI've got an outer an nested gridview.
On the selected index changed of the outer gridview, I do some logic (show/hide buttons somewhere on the page). I also want to have the nested gridview to do the same but the outer gridview is hogging the event and no matter what I try, the sender always stays the outer gridview.
How can I have both the outer and nested gridviews raise their own selected index changed events?
You help is appreciated!
Hey!, great article, I can make this in a few minutes at first try... one doubt, how to make the page go to view the control displayed?? something like an anchor?
ReplyDelete