views:

32

answers:

2

I'm trying to bind a List<String> to a DropDownList in a user control. I think I'm doing the right thing, but it seems that after my code executes the bindings are cleared. Here's the code for review!

User control:

<asp:DropDownList ID="subjectNameDropDown" runat="server"/>
<asp:DropDownList ID="yearLevelDropDown" runat="server"/>

Auto-generated designed code-behind:

public partial class NewSiteMetadataUserControl {
    protected global::System.Web.UI.WebControls.DropDownList subjectNameDropDown;
    protected global::System.Web.UI.WebControls.DropDownList yearLevelDropDown;
}

Code-behind:

public partial class NewSiteMetadataUserControl : UserControl
{
    protected override void CreateChildControls()
    {
        subjectNameDropDown = new DropDownList();
        yearLevelDropDown = new DropDownList();
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        EnsureChildControls();

        // Attempt 1
        List<String> subjectNames = GetSubjectValues();
        foreach (var subjectName in subjectNames)
            subjectNameDropDown.Items.Add(subjectName);
        subjectNameDropDown.DataBind();

        // Attempt 2
        List<String> yearLevels = GetYearLevelValues();
        yearLevelDropDown.DataSource = yearLevels;
        yearLevelDropDown.DataBind();
    }
}

Should this approach work?

If it should, how can I debug what happens after the code executes?

+1  A: 

Yes, this approach should work, here's why it currently isn't,

  • A DropDownList done with DataBind needs a DataSource. This is why Attempt #1 is not working.
  • If you're binding to a List<string>, there is no clear key/value pair to bind to. This is why when binding to a List<Person> (for example), you need to override .ToString() in the Person class to provide the key/value binding, or manually set the DataTextField, DataValueField.
  • There is no way for ASP.NET to work out a key/value pair for a string.

Think about what HTML you want. What should be the key/value for a simple string? Doesn't make sense does it.

Since you don't really care about the "key" (only what is displayed), i suggest you bind to a Dictionary<TKey,TValue> instead.

Either make your method return that, or iterate through the list and add them to the dictionary with an index.

RPM1984
A: 

The problem here was CreateChildControls. Somewhere in my attempts to make this work I added this method that initialises the controls. This isn't necessary and in fact caused the data bindings to be wiped out, as it was automatically called by the framework after OnLoad.

The solution was to remove this method and the call to EnsureChildControls.

Alex Angas