0

Suppose I have several enums representing ... for example database vendors: Unknown, Oracle, Sybase, SQL Server 2005, SQL Server 2008, etc. I want to let the user select between all of these but an Unknown from a Combo Box. When the user selects an enum, they should see a human-readable description (which would hopefully come from an attribute). However, the actual object selected should be an enum of that specific type.

This can be hacked together manually with the help of extra dictionary, but I do not want to do that, and rather use an idiomatic and the cleanest way possible.

Would you kindly share a code sample, or at least a good link?

P.S. Is there an easy way to grab a collection of all enums of the type vendor, except for Unknown (which will have a short/int value of 0, as prescribed by Bill Wagner)?

Hamish Grubijan
  • 10,562
  • 23
  • 99
  • 147
  • possible duplicate of [How do I have an enum bound combobox with custom string formatting for enum values?](http://stackoverflow.com/questions/796607/how-do-i-have-an-enum-bound-combobox-with-custom-string-formatting-for-enum-valu) – nawfal Jun 08 '13 at 23:44

1 Answers1

4

P.S. Is there an easy way to grab a collection of all enums of the type vendor, except for Unknown (which will have a short/int value of 0, as prescribed by Bill Wagner)?

DbVendor[] values = Enum.GetValues(typeof(DbVendor))
                        .Cast<DbVendor>()
                        .Where(v => v != DbVendor.Unknown)
                        .ToArray();

To associate a friendly name to the values, you can use DescriptionAttribute, as shown in this answer. Handle the Format event of the ComboBox to display the description:

private void comboBoxVendor_Format(object sender, ListControlConvertEventArgs e)
{
    DbVendor vendor = (DbVendor)e.ListItem;
    e.Value = vendor.GetDescription();
}

Note: if your application needs to be localizable, the Description attribute is probably not the best option. Instead, you could use string resources with names like DisplayName_DbVendor_Oracle, DisplayName_DbVendor_SqlServer, etc. You can then retrieve the display name for a value as follows:

DbVendor vendor = ...;
string displayName = Properties.Resources.ResourceManager.GetString("DisplayName_DbVendor_" + vendor);

EDIT: if you need to sort the values by description, just change the LINQ query as follows:

DbVendor[] values = Enum.GetValues(typeof(DbVendor))
                        .Cast<DbVendor>()
                        .Where(v => v != DbVendor.Unknown)
                        .OrderBy(v => v.GetDescription())
                        .ToArray();
Community
  • 1
  • 1
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • Some follow-ups: A) Do I need to materialize the `IEnumerable` of enums to an array, before I can feed it into a WinForm combo box at run time? B) On ordering of these items - will the list of enums maintain the order in which they were declared? If I wanted to sort explicitly by the description, then how would I need to modify that LINQ query? – Hamish Grubijan Nov 20 '10 at 22:52
  • 1
    A) I'm not sure how it would work if you just assigned the IEnumerable directly to the DataSource... I usually use ToArray or ToList to make sure the query will be executed only once. B) see my edit – Thomas Levesque Nov 20 '10 at 23:00