Search code examples
c#asp.netlistboxweb-controls

PerformDataBinding not firing in DataBoundControlAdapter for ListBox


I am trying to create a DataBoundControlAdapter for the ListBox Control, but for some reason its not firing the PerformDataBinding method in my DataBoundControlAdapter.

According to the MSDN Documentation:

The PerformDataBinding method is called in place of the DataBoundControl.PerformDataBinding method when a DataBoundControlAdapter control adapter is attached to a control derived from the DataBoundControl class.

Which is not happening at all, any ideas?

Here is basically how it works.

BrowserFile:

<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter
          controlType="System.Web.UI.WebControls.ListBox"
          adapterType="SomeNameSpace.ListBoxDataAdapter" />
    </controlAdapters>
  </browser>
</browsers>

The Adapter:

namespace SomeNameSpace
{
    public class ListBoxDataAdapter : DataBoundControlAdapter
    {
        protected override void PerformDataBinding(System.Collections.IEnumerable data)
        {
            base.PerformDataBinding(data); // Not firing
        }
    }
}

On the page:

<asp:ListBox runat="server" ID="lbxStuff" DataSourceID="obsStuff" DataValueField="Value"
    DataTextField="Text></asp:ListBox>
<asp:ObjectDataSource runat="server" ID="obsStuff" TypeName="Test" SelectMethod="Get">
</asp:ObjectDataSource>

Solution

  • The DataBoundControl (base class for the ListControl/ListBox) contains a method called PerformSelect, this method retrieves data from the adapter (if one exists that is)

    But whoever (at microsoft) that created the ListControl overrode the PerformSelect method and didnt include the adapter in their override, thereby removing the adaptability - thanks to this you wont be able to simply create your own PerformDataBinding method like nature intended.

    All is not lost though, in your DataBoundControlAdapter you can attach to the databinding method of the ListBox get the ObjectDataSource, retrieve the data "manually", call the PerformDataBinding method and then cancel the ObjectDataSource from being called again (else whatever you do will be overriden).

    Like seen in the following ugly "hack".

    void listBox_DataBinding(object sender, EventArgs e)
    {
        ObjectDataSource ods = listBox.DataSourceObject as ObjectDataSource;
        if (ods != null)
        {
            IEnumerable data = ods.Select();
            PerformDataBinding(data);
            ods.Selecting += (s, ev) => { ev.Cancel = true; };
        }
    }
    

    I would almost be inclined to say that you'll be better off by "sub classing" the ListBox, but since you're using an Adapter I guess thats something you dont really want to do?