1
votes

I want to use a C# Windows Forms combo box to select the value of an enum:

    this.comboBoxColor.DataSource = System.Enum.GetValues(typeof(System.Drawing.KnownColor));

But when I put this in the InitializeComponent, it replaces this line with a static assignment of an array with all items in the enum. It does this twice, once for the Datasource, and once for the Items property.

But these things don't work together. When having a bound DataSource, adding items to the Items list causes an error and when doin it the other way around assigning the SelectedValue property doesn't work any more.

I've tried using a separate method to do this outside the InitializeComponent method. And simply setting the DataSource as above in the separate method produces the following error:
System.InvalidOperationException: 'Can't set the SelectedValue in a ListControl with an empty ValueMember.'

Edit: Microsoft says using a simple array as a data source should be possible: https://msdn.microsoft.com/nl-nl/library/x8160f6f(v=vs.110).aspx
It's possible to specify the data source in the designer, but there it only allows selecting classes. What must a class implement to make that work?

1
You shouldn't add anything in the InitializeComponent. It is rewritten by the Forms Designer each time you change something in your form design with the UI interface.Steve
And about your datasource/items problems. The two don't work together you should choose which one you want to use. By the way, how to you think to add something to the KnownColor enumeration?Steve
I've added my own method to call after InitializeComponent. I don't want to add anything to the KnownColor enumeration. I want to select a value from that enum with my ComboBox.MrFox

1 Answers

1
votes

You can write a simple method that transforms your enum to a datatable and then use the result of the method as a DataSource with a pair of well known names for the ValueMember and DisplayMember properties of the combo

public DataTable CreateTableFromEnum(Type t)
{
    DataTable dt = new DataTable();
    if (t.IsEnum)
    {
        dt.Columns.Add("key", t);
        dt.Columns.Add("text", typeof(string));

        foreach(var v in Enum.GetValues(t))
            dt.Rows.Add(v, v.ToString());
    }
    return dt;

}

and call it with

var colors = CreateTableFromEnum(typeof(KnownColor));
cbo.ValueMember = "key";
cbo.DisplayMember = "text";
cbo.DataSource = colors;

Now when you look at the selected value you will get the numeric value of the color selected