Blog Home  Home Feed your aggregator (RSS 2.0)  
Implements IVillage - Ajax
It takes a village to keep up with .Net
 
 Tuesday, December 05, 2006

When workin with the Accordion control in my previous post, I encountered a bug that made life a bit frustrating.  Everytime I broke into the debugger on the ItemDataBound event handler and expanded the event - Crash!  Whenever the display got to e.Item, things stopeed and got funky.  Stop debug and restart.  Create a watch for e.AccordionItem... don't expand the evil e.  I finally took some time and dove into the Accirdion's source code.

I kept looking at this over and over again and could not figure out what was going on and then it clicked - Stack Overflow!  There is a recursive call in the AccordionItemEventArgs class:

        /// <summary>
        /// Container
        /// </summary>

        private IDataItemContainer DataItem
        {
            get { return Item as IDataItemContainer; }
        }

        /// <summary>
        /// DataItem being bound to the Container
        /// </summary>

        public object Item
        {
            get { return DataItem.DataItem; }
        }

When the debugger evaluates Item to display it for you, it calls the DataItem property which in turn calls the Item property and so on...

Going to submit this to the Ajax bug list.  I am modifying my copies definition of the Item property as follows:

        /// <summary>
        /// DataItem being bound to the Container
        /// </summary>
        public Object Item
        {
            get { return _item.DataItem; }
        }  
Wednesday, December 06, 2006 12:59:24 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]    |  |   | 
 Monday, December 04, 2006

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.

Tuesday, December 05, 2006 12:35:55 AM (Eastern Standard Time, UTC-05:00)  #    Comments [14]    |  |   | 
Copyright © 2010 Christian M Loris. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.