In one of our migration project we have a Silverlight project. Most of the controls used in that project are custom controls. In one of its functionality, a grid containing the records of child and parent gets loaded. Initially only the parent details gets loaded with one expand symbol next to it. On clicking expand button child details gets loaded.
I need to know what exactly is happening behind the scene when we are clicking on expand button. When child records are more it takes time to load. I tried to debug but no postback call is happening.
Let me know in case you need more detail.
Please guide.
So, assuming you are dumping silverlight?
Then to nest a grid, you can say drop in a listview, and then inside of the listview, we drop in a grid view. You can try and nest two gridviews, but I find they don't work well, but a listview for the main grid, and then for child grid, then a grid view is just fine.
So, markup will look say like this (listview, then nested gridview).
<asp:ListView ID="ListView1" runat="server" DataKeyNames="ID" >
<ItemTemplate>
<tr style="">
<td><asp:Button ID="cmdView" runat="server" Text="+" onclick="cmdView_Click" /></td>
<td><asp:Label ID="HotelNameLabel" runat="server" Text='<%# Eval("HotelName") %>' /></td>
<td><asp:Label ID="CityLabel" runat="server" Text='<%# Eval("City") %>' /></td>
<td><asp:Label ID="ProvinceLabel" runat="server" Text='<%# Eval("Province") %>' /></td>
<td><asp:Label ID="DescriptionLabel" runat="server" Text='<%# Eval("Description") %>' /></td>
</tr>
<tr>
<td colspan="5">
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table table-hover" style="display:none;margin-left:3%;width:97%" >
<Columns>
<asp:BoundField DataField="Firstname" HeaderText="Firstname" SortExpression="Firstname" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:CheckBox ID="ckSel" runat="server" OnCheckedChanged="ckSel_CheckedChanged"
AutoPostBack="true"></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" class = "table table-hover" >
<tr runat="server" style="">
<th runat="server">View</th>
<th runat="server">HotelName</th>
<th runat="server">City</th>
<th runat="server">Province</th>
<th runat="server">Description</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
Now to be fair, above is about as much mark-up we would include in a post on SO (any more, and no one will read or bother with this post.
Ok, so the code to load up the listview (the main part). Would be this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid()
End If
End Sub
Sub LoadGrid()
Dim strSQL As String
strSQL = "SELECT * FROM tblHotels WHERE ID in (select hotel_Id from People)
ORDER BY HotelName"
Using cmdSQL As New SqlCommand(strSQL, New SqlConnection(My.Settings.TEST4))
cmdSQL.Connection.Open()
ListView1.DataSource = cmdSQL.ExecuteReader
ListView1.DataBind()
End Using
End Sub
Output:
Ok, so now we need the code for the "+" button. When clicked, it will expand, and show the child gridview.
That code is like this:
Protected Sub cmdView_Click(sender As Object, e As EventArgs)
Dim cmd As Button = sender
'Dim gVR As ListViewDataItem = ListView1.Items(ListView1.SelectedIndex)
Dim gVR As ListViewDataItem = cmd.Parent
Dim gChild As GridView = gVR.FindControl("GridView2") ' pluck out the grid for this row
If gChild.Style("display") = "normal" Then
' if grid is already display, then hide it, and exit
gChild.Style("display") = "none"
Exit Sub
End If
gChild.Style("display") = "normal"
Dim HotelPK As String = ListView1.DataKeys(gVR.DataItemIndex).Item("ID")
' only re-load if never loaded (can't re-load else blow out check boxes
If gChild.Rows.Count = 0 Then
Dim strSQL As String
strSQL = "SELECT * from People where hotel_id = " & HotelPK
Using cmdSQL As New SqlCommand(strSQL, New SqlConnection(My.Settings.TEST4))
cmdSQL.Connection.Open()
gChild.DataSource = cmdSQL.ExecuteReader
gChild.DataBind()
End Using
End If
End Sub
Note how the child rows are NOT loaded until you click. Clicking on a + button this results in this:
And the state of the expand/close does remain intact.
And thus now if we expand again, then the data does not have to be re-loaded.