views:

1953

answers:

8

Hi, a lot of people have answered the question of how to bind an enum to a combo box in WinForms. Its like this:

comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));

But that is pretty useless without being able to set the actual value to display.

I have tried:

comboBox1.SelectedItem = MyEnum.Something; // Does not work. SelectedItem remains null

I have also tried:

comboBox1.SelectedIndex = Convert.ToInt32(MyEnum.Something); // ArgumentOutOfRangeException, SelectedIndex remains -1

Does anyone have any ideas how to do this?

A: 

Try:

comboBox1.SelectedItem = MyEnum.Something;

EDITS:

Whoops, you've tried that already. However, it worked for me when my comboBox was set to be a DropDownList.

Here is my full code which works for me (with both DropDown and DropDownList):

public partial class Form1 : Form
{
    public enum BlahEnum
    { 
        Red,
        Green,
        Blue,
        Purple
    }

    public Form1()
    {
        InitializeComponent();

        comboBox1.DataSource = Enum.GetValues(typeof(BlahEnum));

    }

    private void button1_Click(object sender, EventArgs e)
    {
        comboBox1.SelectedItem = BlahEnum.Blue;
    }
}
rein
A: 

You could use the "FindString.." functions:

Public Class Form1
    Public Enum Test
        pete
        jack
        fran
        bill
    End Enum
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ComboBox1.DataSource = [Enum].GetValues(GetType(Test))
        ComboBox1.SelectedIndex = ComboBox1.FindStringExact("jack")
        ComboBox1.SelectedIndex = ComboBox1.FindStringExact(Test.jack.ToString())
        ComboBox1.SelectedIndex = ComboBox1.FindStringExact([Enum].GetName(GetType(Test), Test.jack))
        ComboBox1.SelectedItem = Test.bill
    End Sub
End Class
A: 
comboBox1.SelectedItem = MyEnum.Something;

should work just fine ... How can you tell that SelectedItem is null?

bruno conde
I can check it in the debugger. I assume it is because the type of SelectedItem is object, i.e. a reference type, and enums are value types. Although I would have expected the compiler to catch that.
A: 

You can use a list of KeyValuePair values as the datasource for the combobox. You will need a helper method where you can specify the enum type and it returns IEnumerable> where int is the value of enum and string is the name of the enum value. In your combobox, set, DisplayMember property to 'Key' and ValueMember property to 'Value'. Value and Key are public properties of KeyValuePair structure. Then when you set SelectedItem property to an enum value like you are doing, it should work.

Mehmet Aras
A: 

At the moment I am using the Items property rather than the DataSource, it means I have to call Add for each enum value, but its a small enum, and its temporary code anyway.

Then I can just do the Convert.ToInt32 on the value and set it with SelectedIndex.

Temporary solution, but YAGNI for now.

Cheers for the ideas, I will probably use them when I do the proper version after getting a round of customer feedback.

A: 

...but its a small enum, and its temporary code anyway

A very poor excuse. Might as well do it right from the start because you --will not-- go back and change it.

Nope, that's YAGNI, no point spending a lot of time on something that doesn't suit the customer's needs.And of course I will go back and change it, as soon as the customer asks me to. And the change is likely to involve something completely different. This way I only have to throw away a few minutes work, if I did it "properly" I would likely have to throw away hours worth.I agree, there is a fine line between incurring technical debt, and YAGNI, and I always do it right with the library code and business object stuff, but the gui stuff gets turned over multiple times before final release.
+1  A: 

The code

comboBox1.SelectedItem = MyEnum.Something;

is ok, the problem must reside in the DataBinding. DataBinding assignments occur after the constructor, mainly the first time the combobox is shown. Try to set the value in the Load event. For example, add this code:

protected override void OnLoad(EventArgs e)
{
  base.OnLoad(e);
  comboBox1.SelectedItem = MyEnum.Something;
}

And check if it works.

jmservera
A: 

I use the following helper method, which you can bind to your list.

    ''' <summary>
    ''' Returns enumeration as a sortable list.
    ''' </summary>
    ''' <param name="t">GetType(some enumeration)</param>
    Public Shared Function GetEnumAsList(ByVal t As Type) As SortedList(Of String, Integer)

        If Not t.IsEnum Then
            Throw New ArgumentException("Type is not an enumeration.")
        End If

        Dim items As New SortedList(Of String, Integer)
        Dim enumValues As Integer() = [Enum].GetValues(t)
        Dim enumNames As String() = [Enum].GetNames(t)

        For i As Integer = 0 To enumValues.GetUpperBound(0)
            items.Add(enumNames(i), enumValues(i))
        Next

        Return items

    End Function
ScottE