tags:

views:

1760

answers:

4

We are binding a list of custom objects to an ASP.NET DropDownList in C# but we want to allow for the DropDownList to not have anything selected initially. One way of doing this might be to create an intermediate list of strings, populate the first one with an empty string and then populate the rest of the list with the custom object information.

This doesn't seem very elegant however, does anyone have a better suggestion?

+11  A: 

Yes, create your list like so:

<asp:DropDownList ID="Whatever" runat="server" AppendDataBoundItems="True">
    <asp:ListItem Value="" Text="Select one..." />
</asp:DropDownList>

(Note the use of AppendDataBoundItems="True")

And then when you bind, the bound items are put after the empty item rather than replacing it.

Sean Bright
Wow what a simple task
Sauron
+5  A: 

You could add to the databound event:

protected void DropDownList1_DataBound(object sender, EventArgs e)
        {
            DropDownList1.Items.Insert(0,new ListItem("",""));
        }
Richard
pretty much the way I have been doing it for years, or not even in te DataBound but anytime after you set the DataSource +1
SomeMiscGuy
+1  A: 

Just working on this actually, here's what I got so far (along with a couple databinding goodies)

public interface ICanBindToObjectsKeyValuePair {
    void BindToProperties<TYPE_TO_BIND_TO>(IEnumerable<TYPE_TO_BIND_TO> bindableEnumerable, Expression<Func<TYPE_TO_BIND_TO, object>> textProperty, Expression<Func<TYPE_TO_BIND_TO, object>> valueProperty);
}

public class EasyBinderDropDown : DropDownList, ICanBindToObjectsKeyValuePair {
    public EasyBinderDropDown() {
        base.AppendDataBoundItems = true;
    }
    public void BindToProperties<TYPE_TO_BIND_TO>(IEnumerable<TYPE_TO_BIND_TO> bindableEnumerable,
        Expression<Func<TYPE_TO_BIND_TO, object>> textProperty, Expression<Func<TYPE_TO_BIND_TO, object>> valueProperty) {
        if (ShowSelectionPrompt)
            Items.Add(new ListItem(SelectionPromptText, SelectionPromptValue));
        base.DataTextField = textProperty.MemberName();
        base.DataValueField = valueProperty.MemberName();
        base.DataSource = bindableEnumerable;
        base.DataBind();
    }
    public bool ShowSelectionPrompt { get; set; }
    public string SelectionPromptText { get; set; }
    public string SelectionPromptValue { get; set; }
    public virtual IEnumerable<ListItem> ListItems {
        get { return Items.Cast<ListItem>(); }
    }
}

Notice one thing that you can do is

dropDown.BindToProperties(myCustomers, c=>c.CustomerName, c=>c.Id);
George Mauer
+1  A: 

First:

DropDownList1.Items.Clear();

Then add listItems to the dropDownList.

This prevents the dropDownList from acquiring an ever increasing list of items every time it is rendered in a postback or asynchronous postback.

soaringCelia
This doesn't really answer the question, but +1 because when I just started with ASP.NET, I needed to know this badly, hehe :) Took me a few hours to figure it out.
SirDemon