Hamish Grubijan
Hamish Grubijan

Reputation: 10820

How to stick an enum into a .Net WinForm ComboBox

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)?

Upvotes: 0

Views: 536

Answers (1)

Thomas Levesque
Thomas Levesque

Reputation: 292415

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();

Upvotes: 4

Related Questions