views:

1927

answers:

3

If I bind a WinForms ComboBox to an enum type's values, i.e.

combo1.DropDownStyle = ComboBoxStyle.DropDownList;
combo1.DataSource = Enum.GetValues(typeof(myEnumType));

Who knows how I could achieve the same result, while, in addition to entries matching each enum value, I can also have a blank entry representing no selection?

I cannot simply add a special value to the enum type because this must be flexible to deal with any enum type.

I'd appreciate your help.

Edit: I should make clear that I want to bind the actual enum values and not their names. If the actual enum values are bound, the ComboBox takes care of calling their ToString() to get the text to display.

+3  A: 

You could try something like this:

(Edited to reflect Brad_Z's excellent suggestion)

static IEnumerable<String> getValues<T>(String initialValue)
{
    yield return initialValue;

    foreach (T t in Enum.GetValues(typeof(T)))
     yield return t.ToString();
}

static IEnumerable<String> getValues<T>()
{
    return getValues<T>(String.Empty);
}

This will allow you to bind to the results of this function like this:

combo1.DataSource = getValues<myEnumType>().ToArray();

or like this, if you wish to specify a different value for the initial item:

combo1.DataSource = getValues<myEnumType>("Select").ToArray();
Andrew Hare
Good answer. I'd add a parameter to the getValues function allowing the text of the blank entry to be specified. So you could say: getValues<catEnumType>("select a cat").ToArray();
Brad_Z
Excellent suggestion! I have edited to include it. :)
Andrew Hare
Thanks for your post - That would work handsomely, except it is the actual enum values that I want and not a string representation of their names :-)
frou
+4  A: 

Not sure if you guys have tried all of the code that you've been posting or not, but you can't add items do a databound ComboBox. This is winforms, not WPF, so there is no "DataBind" function.

You could do this:

public static string[] GetEnumValues<T>(bool includeBlank) 
{
    List<string> values = new List<string>((Enum.GetValues(typeof(T)) as T[]).Select(t => t.ToString()));

    if (includeBlank)
    {
        values.Insert(0, string.Empty);
    }

    return values.ToArray();
}

Then

combo.DataSource = GetEnumValues<myEnumType>(true);
Adam Robinson
A: 

(Please see my edit to the question where I clarified that I don't want to bind to a collection of strings).

After more fiddling, the following monstrosity seems to work. combo1.SelectedItem is of type object and will either be a DBNull or a (boxed?) enum value. Is this code advisable?

combo1.DataSource = (new object[] { DBNull.Value }
                        .Concat(Enum.GetValues(refToAnEnumType)
                            .Cast<object>())).ToList()

Edit: I see Adam and Andrew's methods could easily be adapted to do the same thing. Thanks guys!

frou