I was recently using the Ajax Accordion control on a project which required me to do some databinding with it. I was accessing more than one object to fill out the Accordion panels so I wanted to set alot of the controls during the ItemDataBound event of the control. I quickly became frustrated as I could not find the controls in the AjaxContentPanel being made available to me in the AccordionItemEventArgs. Here is what I was working with:
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
<cc1:Accordion ID="Accordion1" runat="server">
<Panes></Panes>
<HeaderTemplate>
<div style="background-color:blue;cursor:pointer;">
Header: <!--%# Eval("Key") %--> /
<asp:Label ID="lblHeader" runat="server" Text="Label"></asp:Label>
</div>
</HeaderTemplate>
<ContentTemplate>
<div style="background-color:Silver;padding:5px;border:thin white inset;">
Data: <!--%# Eval("Value") %-->
<asp:Label ID="lblData" runat="server" Text="Label"></asp:Label>
</div>
</ContentTemplate>
</cc1:Accordion>
</div>
</form>
I built a simple dictionary for this example to do the data binding.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Dim values As Dictionary(Of String, String) = New Dictionary(Of String, String)()
values("A") = "This is the value for A"
values("B") = "This is the value for B"
values("C") = "This is the value for C"
values("D") = "This is the value for D"
Accordion1.DataSource = values
Accordion1.DataBind()
End If
End Sub
This is what my first attempt to set the labels in the code.
Protected Sub Accordion1_ItemDataBound(ByVal sender As Object, ByVal e As AjaxControlToolkit.AccordionItemEventArgs) Handles Accordion1.ItemDataBound
Dim myDictEntry As KeyValuePair(Of String, String)
Dim lblHeader As Label
Dim lblData As Label
myDictEntry = e.AccordionItem.DataItem
lblHeader = e.AccordionItem.FindControl("lblHeader")
lblHeader.Text = myDictEntry.Key
lblData = e.AccordionItem.FindControl("lblData")
lblData.Text = myDictEntry.Value
End Sub
I kept getting null reference exceptions on the 'lblData.Text = myDictEntry.Value' line. I went into the locals to see what was going on with my eventArgs. I rapidly found out that you don't want to touch e.Item*. Any attempt to look at these caused the debugger to drop. Not fun. I poked around extensively in e.AccordionItem which is an AccordionContentPanel. So it became apprent after digging around in the controls source that there are two types of ContentPanels in each AccordionItem. There is a Content and Header panel. And you can tell which is which by examining e.AccordionItem.ItemType.
This is the second attempt which now workd flawlessly.
Protected Sub Accordion1_ItemDataBound(ByVal sender As Object, ByVal e As AjaxControlToolkit.AccordionItemEventArgs) Handles Accordion1.ItemDataBound
Dim myDictEntry As KeyValuePair(Of String, String)
Dim lblHeader As Label
Dim lblData As Label
myDictEntry = e.AccordionItem.DataItem
If e.AccordionItem.ItemType = AjaxControlToolkit.AccordionItemType.Header Then
lblHeader = e.AccordionItem.FindControl("lblHeader")
lblHeader.Text = myDictEntry.Key
Else
lblData = e.AccordionItem.FindControl("lblData")
lblData.Text = myDictEntry.Value
End If
End Sub
I was suprised how this particular attribute was buried so deeply in the eventArgs. I would have expected to see an e.AccordionItemType hanging out to make it a little more obvious. Overall, I do love this control. A nice way to present a large amount of content on a page without it running off the bottom of the screen. And the panel sliding is just too cool.