Accordion control and databinding

Last post 03-23-2007 8:12 AM by donoho. 14 replies.

Sort Posts:

  • Accordion control and databinding

    01-18-2007, 1:43 PM
    • Loading...
    • Heleboel
    • Joined on 01-18-2007, 6:28 PM
    • Geldermalsen, The Netherlands
    • Posts 15

    Today I tried to implement some <%# %> databindings in my website, on the same page as were an accordion control exists. To bind the <%# %> stuff to the data, I added a 'DataBind()' call to the Page_Load function of my page. I was very surprised to see that all panes of the Accordion control were gone! For your information, the panes of the Accordion control did not contain any databinding controls, only some links.


    Removing the DataBind() call from the Page_Load function let the Accordion control work normally, adding the DataBind() function causes the Accordion control to misbehave.

    Anybody seen this before? And were can I report this bug?
     

    Filed under: , ,
  • Re: Accordion control and databinding

    01-18-2007, 10:12 PM
    • Loading...
    • cloris
    • Joined on 09-19-2003, 4:01 PM
    • Melbourne, FL USA
    • Posts 158

    I put a pretty good example of this on my blog where you actually bind to controls in the accordion templates.  You can use the <%# %> syntax with the example as long as you get rid of the itemdatabound handler.  Let me know if this helps!

    http://www.implementsivillage.net/PermaLink,guid,61ab3cf2-d52c-4a01-ac53-78f3c64844da.aspx

    Christian Loris
    cloris@cfl.rr.com
    http://www.implementsivillage.net
  • Re: Accordion control and databinding

    01-19-2007, 1:34 AM
    • Loading...
    • Heleboel
    • Joined on 01-18-2007, 6:28 PM
    • Geldermalsen, The Netherlands
    • Posts 15

    Thank you for your response, Cloris. Unfortunately, it is not exactly my problem.

    The problem can be reproduced as follows: start with a new, empty aspx page, add an Accordion to it, fill it with some stuff (do not use any databinding stuff) and run the page. All will work fine.

    And then, add the following statement to the "Page_Load" method in the code behind: "DataBind();". Nothing more, nothing less.

    Build and run the page, and the panes of the Accordion are completely gone. Viewing the source of the page in the browser will show an empty <div>-tag. 

    My guess is that something goes wrong when the DataBind call tries to bind the Accordion control to some data, but since the Accordion control does not contain any datasources or something, it goes wrong.
  • Re: Accordion control and databinding

    01-19-2007, 1:57 AM
    • Loading...
    • Heleboel
    • Joined on 01-18-2007, 6:28 PM
    • Geldermalsen, The Netherlands
    • Posts 15

    I have been digging around in the source code, and I found this:

     

            /// <summary>
            /// Bind the Accordion to its DataSource
            /// </summary>
            public override void DataBind()
            {
                // Don't databind to a data source control when the control is in the designer but not top-level
                if (IsBoundUsingDataSourceID && DesignMode && (Site == null))
                    return;
    
                // do our own databinding
                RequiresDataBinding = false;
                OnDataBinding(EventArgs.Empty);
            }
    
            /// <summary>
            /// DataBind the Accordion to its panes
            /// </summary>
            /// <param name="e">EventArgs</param>
            protected override void OnDataBinding(EventArgs e)
            {
                base.OnDataBinding(e);
    
                // reset the control state
                ClearPanes();
                ClearChildViewState();
    
                // and then create the control hierarchy using the datasource
                CreateControlHierarchy(true);
                ChildControlsCreated = true;
            }
    
    
    I think it is the 'ClearPanes();' call; this call should not be made when there is/are no datasources bound to the Accordion control. Therefore, in the DataBind() function, there should be an extra if statement to check for the existence of a datasource, and if no one exist, the function should return without calling the OnDataBinding.
  • Re: Accordion control and databinding

    01-19-2007, 6:57 AM
    • Loading...
    • Heleboel
    • Joined on 01-18-2007, 6:28 PM
    • Geldermalsen, The Netherlands
    • Posts 15

    And again I am replying onto my own post, I hope you would not blame me for that.

    I did some further investigation in the source code and I managed to 'debug' it. I modified the code slightly into the following:

     

            /// <summary>
            /// DataBind the Accordion to its panes
            /// </summary>
            /// <param name="e">EventArgs</param>
            protected override void OnDataBinding(EventArgs e)
            {
                base.OnDataBinding(e);
    
                if (DataSource != null)
                {
                   // reset the control state
                   ClearPanes();
                   ClearChildViewState();
    
                   // and then create the control hierarchy using the datasource
                   CreateControlHierarchy(true);
                   ChildControlsCreated = true;
                }
                else
                {
                   foreach (object ChildControl in Controls)
                   {
                      if (ChildControl is System.Web.UI.WebControls.WebControl)
                      {
                         System.Web.UI.WebControls.WebControl lWebControl = (System.Web.UI.WebControls.WebControl)ChildControl;
                         lWebControl.DataBind();
    
                         foreach (object ChildControl1 in lWebControl.Controls)
                         {
                            if (ChildControl1 is AjaxControlToolkit.AccordionContentPanel )
                            {
                               AjaxControlToolkit.AccordionContentPanel lAccPanel = (AjaxControlToolkit.AccordionContentPanel)ChildControl1;
    
                               foreach (object ChildControl2 in lAccPanel.Controls)
                               {
                                  ChildControl2.GetType();
    
                                  if (ChildControl2 is System.Web.UI.DataBoundLiteralControl)
                                  {
                                     System.Web.UI.DataBoundLiteralControl lLiteral = (System.Web.UI.DataBoundLiteralControl)ChildControl2;
    
                                     lLiteral.DataBind();
                                  }
                               }
                            }
                         }
                      }
                   }
                }
            }
    
    

    As you can see, I placed a 'if ( DataSource != null )' around the original code. This is to avoid clearing the panes when there is no datasource to create new panes (with headers and content).

    Further, in the else clause, I walk the child controls of the Accordion control some levels deep until I find some DataBoundLiteralControls, for which I then call the DataBind method. This is to bind controls with databinding stuff that are inside the AccordionPanels, for example hyperlinks or labels that must be modified.

    I wonder why the 'base.OnDatabinding(e)' does not databind the child controls, but people with more indepth insight than I have should look at that, and I hope that someone of the AjaxControlToolkit developers will have a look at this.


  • Re: Accordion control and databinding

    01-19-2007, 4:44 PM
    • Loading...
    • cloris
    • Joined on 09-19-2003, 4:01 PM
    • Melbourne, FL USA
    • Posts 158
    This behaviour with just calling DataBind is totally expected.  You have not set a data sours, so when the control goes to bind, there is nothing.  So it renders nothing... none of the panes... nothing.
    Christian Loris
    cloris@cfl.rr.com
    http://www.implementsivillage.net
  • Re: Accordion control and databinding

    01-19-2007, 4:48 PM
    • Loading...
    • cloris
    • Joined on 09-19-2003, 4:01 PM
    • Melbourne, FL USA
    • Posts 158
    I think the bottom line here is that you don't call databind on a control unless you have a datasource set on the control.  What is it you are really trying to accomplish here? 
    Christian Loris
    cloris@cfl.rr.com
    http://www.implementsivillage.net
  • Re: Accordion control and databinding

    01-20-2007, 1:09 AM
    • Loading...
    • Heleboel
    • Joined on 01-18-2007, 6:28 PM
    • Geldermalsen, The Netherlands
    • Posts 15

    Well, I have made a masterpage with a menu, build with an Accordion control. This menu contains links to other pages on my website, but I planned to make my website multicultural (in fact, for 2 languages, dutch and english). So, the links in the Content panels of the AccordionPanes show like this:

        <a href="http://forums.asp.net/<%# mCulture %>/about/contact/contact.aspx">Contact</a>,

    where the mCulture expands to "nl" or "en" when DataBind is called. And I called the Databind in the Page_Load event of the masterpage. That's what I'm trying to accomplish.

    But, my point in this case is: when you have some databinding stuff in your page (whether or not in the Accordion), calling DataBind() on the page (in the Page_Load event) must not delete the AccordionPanes when it has no DataSource! In that case, the developer may have an Accordion with static data, which must not be overwritten or deleted!

    By the way, the "if ( DataSource != null )" statement comes straightly from the microsoft documentation on the DataBind method!
     

  • Re: Accordion control and databinding

    01-21-2007, 9:25 PM
    • Loading...
    • cloris
    • Joined on 09-19-2003, 4:01 PM
    • Melbourne, FL USA
    • Posts 158
    I see your deilemna now.  I am curious, I have been digging into the accordion a bit and wander if there are any other controls like it.  I mean controls that let you either define the content staticly and dynamicly (databound).  I was digging into some of the known bugs for accordion and they seem to surround the fact it tries to exhibit both behaviours.  Do you know of any controls similar to this?
    Christian Loris
    cloris@cfl.rr.com
    http://www.implementsivillage.net
  • Re: Accordion control and databinding

    01-22-2007, 1:20 AM
    • Loading...
    • Heleboel
    • Joined on 01-18-2007, 6:28 PM
    • Geldermalsen, The Netherlands
    • Posts 15

    No, I have been playing with AJAX for a month or so, and the accordion is the first control that I used on my website.

    How can I ask the development team of the AJAC control toolkit to take a look at my problem?

    Thanks!
     

  • Re: Accordion control and databinding

    01-22-2007, 8:39 AM
    • Loading...
    • cloris
    • Joined on 09-19-2003, 4:01 PM
    • Melbourne, FL USA
    • Posts 158

    The develoment community for the control toolkit is located at

    http://www.codeplex.com/AtlasControlToolkit

    I have looked at the source for the control as an introduction into Ajax control development. It has me baffled on how you can make a control behave as both databound and stat render.  I am anxious for them to fix it so I can understand this a little better.  If you go to the site, there is a bug tracker where you can view open/closed bugs and submit new ones.

    Christian Loris
    cloris@cfl.rr.com
    http://www.implementsivillage.net
  • Re: Accordion control and databinding

    01-24-2007, 10:14 AM
    • Loading...
    • Heleboel
    • Joined on 01-18-2007, 6:28 PM
    • Geldermalsen, The Netherlands
    • Posts 15

    Well, it should be simple:

    If there is a datasource specified, use it to build the accordion with that data.

    If there is no datasource specified, recusively walk the child controls and call "DataBind()" on them.
     

  • Re: Accordion control and databinding

    01-24-2007, 4:42 PM
    • Loading...
    • cloris
    • Joined on 09-19-2003, 4:01 PM
    • Melbourne, FL USA
    • Posts 158
    I think there is a little more to it than that.  I am no control expert, but there is alot of things that go on during the lifecycle of a control during load that make this inherently difficult.  Controls initialize prior to control state being available so there is no way to tell the data source is present let alone if the control is being posted back to or not.  It's pretty hairy.  Anyone have any thoughts?
    Christian Loris
    cloris@cfl.rr.com
    http://www.implementsivillage.net
  • Re: Accordion control and databinding

    02-19-2007, 2:50 PM
    • Loading...
    • joelevi
    • Joined on 09-18-2006, 11:00 PM
    • Syracuse, Utah, USA
    • Posts 3

    Are you trying to accomplish something like this? 

    <asp:scriptmanager ID="Scriptmanager1" runat="server" />

    <ajaxToolkit:Accordion ID="MyAccordion" runat="Server" SelectedIndex="0" HeaderCssClass="accordionHeader" ContentCssClass="accordionContent" AutoSize="None" FadeTransitions="true" TransitionDuration="250" FramesPerSecond="40" DataSourceID="SqlDataSource1">

    <Panes> </Panes>

    <HeaderTemplate> <a href="" onclick="return false;"><%# Eval("Title") %></a> </HeaderTemplate>

    <ContentTemplate> <%# Eval("Body") %> </ContentTemplate>

    </ajaxToolkit:Accordion>

     

    - Joe Levi, www.JoeLevi.com 

    - www.JoeLevi.com
  • Re: Accordion control and databinding

    03-23-2007, 8:12 AM
    • Loading...
    • donoho
    • Joined on 03-19-2007, 3:51 PM
    • Silicon Valley, CA
    • Posts 1
    I just ran into this issue when calling Page.DataBind(); in the Page_Load event of a Content Page that had an Accordion on the Master Page.  By changing the Page.DataBind(); to <Control>.DataBind(); the issue was resolved.  I realized it was the Page.DataBind(); when I included it in the Master Page Page_Load event and it never showed up.
    No Excuses!!!