I have a setup using three levels of nesting: A Repeater, the items of which utilize CollapsiblePanelExtenders (which work), and each contain a GridView. Each of these then contain another GridView which is controlled by another CollapsiblePanelExtender. These inner CollapsiblePanels will effectively show either an expanded or collapsed state only if I set clientState to True. However, they do not effectively expand or collapse as expected. Everything is bound dynamically.
Here is the markup...
<asp:Repeater ID="cat_repeater" runat="server">
<ItemTemplate>
<asp:CollapsiblePanelExtender id="cat_cpExt" runat="server" TargetControlID="cat_pnl" CollapsedSize="0" Collapsed="false" CollapsedImage="collapsed.png" ExpandedImage="expanded.png" ExpandControlID="cpControl_pnl" CollapseControlID="cpControl_pnl" TextLabelID="cpControl_lbl" ImageControlID="cpControl_img" CollapsedText='<%#configCPText(eval("Title"), False)%>' ExpandedText='<%#configCPText(eval("Title"), True) %>' />
<asp:Panel ID="cpControl_pnl" runat="server" Visible='<%#itemVisible(eval("ID"), "Recipients", "CategoryID") %>' CssClass="CPanelStyle">
<asp:Image ID="cpControl_img" runat="server" ImageUrl="expanded.png" />
<asp:Label ID="cpControl_lbl" runat="server" Text='<%#configCPText(eval("Title"), True) %>' CssClass="CPanelText" />
</asp:Panel>
<asp:Panel ID="cat_pnl" runat="server">
<asp:GridView ID="recipients_gv" runat="server" CssClass="GVStyle" HeaderStyle-CssClass="GVHeaderStyle" RowStyle-CssClass="GVItemStyle" AutoGenerateColumns="false" GridLines="none" AllowPaging="false">
<Columns>
<asp:TemplateField HeaderText="Name" SortExpression="Last Name" ItemStyle-CssClass="GVNameStyle">
<ItemTemplate>
<asp:Literal id="name_lit" runat="server" text='<%#formatNameText(eval("FirstName"), eval("LastName")) %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Gifts" ItemStyle-Width="500px">
<ItemTemplate>
<asp:CollapsiblePanelExtender id="gifts_cpExt" runat="server" TargetControlID="gifts_pnl" CollapsedSize="0" Collapsed="true" CollapsedImage="collapsed.png" ExpandedImage="expanded.png" ExpandControlID="cpControl_pnl2" CollapseControlID="cpControl_pnl2" TextLabelID="cpControl_lbl2" ImageControlID="cpControl_img2" CollapsedText='<%#configGiftsCPText(eval("ID"), True)%>' ExpandedText='<%#configGiftsCPText(eval("ID"), False) %>' />
<asp:Panel ID="cpControl_pnl2" runat="server" Visible='<%#itemVisible(eval("ID"), "Gifts", "RecipientID") %>'>
<asp:Image ID="cpControl_img2" runat="server" ImageUrl="collapsed.png" />
<asp:Label ID="cpControl_lbl2" runat="server" Text='<%#configGiftsCPText(eval("ID"), False) %>' />
</asp:Panel>
<asp:Panel ID="gifts_pnl" runat="server">
<asp:GridView ID="gifts_gv" runat="server" DataKeyNames="ID" RowStyle-CssClass="GVInnerItemStyle" HeaderStyle-CssClass="GVInnerHeaderStyle" Gridlines="None" AutoGenerateColumns="false" AllowPaging="false" Width="475px">
<Columns>
<asp:TemplateField ItemStyle-CssClass="GVInnerButtonItemStyle" HeaderText="Description">
<ItemTemplate>
<asp:LinkButton ID="gift_lBtn" runat="server" Text='<%#eval("Description") %>' CommandName="Select" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Complete" ItemStyle-Width="50px">
<ItemTemplate>
<asp:CheckBox ID="giftComplete_cbx" runat="server" Checked='<%#eval("Complete") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Panel>
<br />
</ItemTemplate>
</asp:Repeater>
...And here is the code to bind everything:
Protected Sub bindCategories()
Try
oCmd.Connection = oConn
oCmd.CommandType = CommandType.Text
strSQL = "SELECT * FROM Categories"
oCmd.CommandText = strSQL
oDA.SelectCommand = oCmd
oDA.Fill(oDTbl)
cat_repeater.DataSource = oDTbl
cat_repeater.DataBind()
For i As Integer = 0 To oDTbl.Rows.Count - 1
oCmd.Parameters.Clear()
inner_dTbl.Clear()
strSQL = "SELECT *, Title FROM Recipients INNER JOIN Categories on Recipients.CategoryID = Categories.ID WHERE CategoryID = @CategoryID ORDER BY LastName"
oParam = New SqlParameter
oParam.ParameterName = "CategoryID"
oParam.SqlDbType = SqlDbType.Int
oParam.Value = oDTbl.Rows(i)("ID")
oCmd.Parameters.Add(oParam)
oCmd.CommandText = strSQL
oDA.SelectCommand = oCmd
oDA.Fill(inner_dTbl)
Dim gv As GridView = CType(cat_repeater.Items(i).FindControl("recipients_gv"), GridView)
gv.DataSource = inner_dTbl
gv.DataBind()
For j As Integer = 0 To inner_dTbl.Rows.Count - 1
oCmd.Parameters.Clear()
gifts_dTbl.Clear()
strSQL = "SELECT * FROM Gifts WHERE RecipientID = @RecipientID ORDER BY Description"
oParam = New SqlParameter
oParam.ParameterName = "RecipientID"
oParam.SqlDbType = SqlDbType.Int
oParam.Value = inner_dTbl.Rows(j)("ID")
oCmd.Parameters.Add(oParam)
oCmd.CommandText = strSQL
oDA.SelectCommand = oCmd
oDA.Fill(gifts_dTbl)
Dim inner_gv As GridView = CType(gv.Rows(j).FindControl("gifts_gv"), GridView)
inner_gv.DataSource = gifts_dTbl
inner_gv.DataBind()
Dim cpExt As CollapsiblePanelExtender = CType(gv.Rows(j).FindControl("gifts_cpExt"), CollapsiblePanelExtender)
cpExt.Collapsed = True
cpExt.ClientState = True
Next
Next
Catch ex As Exception
Throw ex
End Try
End Sub
I've successfully used CollapsiblePanelExtenders in a 2-level nested GridView setup that without a problem before, and without having to set clientState. However, I've had to specify clientState when using CollapsiblePanelExtenders with Repeaters before.
Does anyone have any input regarding why these extenders will not function in this 3-level nested setup?