WinForms – ComboBox with enum description

By default, when you load enum values into a ComboBox, it’ll show the enum names. If you want to show the enum descriptions (from the [Description] attribute) instead, and still be able to get the selected enum value, you can do the following:

  • Generate a list of objects containing the enum value/description pairs.
  • Set ComboBox.DataSource to this list.
  • Set ComboBox.DisplayMember to the description, and ComboBox.ValueMember to the enum value.
  • Optionally bind an object’s enum property to ComboBox.SelectedValue (not SelectedItem).

I’ll show the code for this below. First, let’s say you have the following enum with descriptions:

using System.ComponentModel;

public enum ProgrammingLanguage
{
	[Description("C#")]
	CSharp,
	[Description("C++")]
	CPlusPlus
}
Code language: C# (cs)

The following code generates anonymous objects with the enum value and description (get the [Description] attribute with reflection), uses it as the data source, and sets DisplayMember and ValueMember to the anonymous type property names:

//Can get the enum type 1) Hardcoded 2) From generic T parameter 3) From reflected property type
Type enumType = typeof(ProgrammingLanguage);

var enumValuesAndDescriptions = new ArrayList();

foreach (var e in Enum.GetValues(enumType))
{
	enumValuesAndDescriptions.Add(new
	{
		EnumValue = e,
		EnumDescription = (e.GetType().GetMember(e.ToString()).FirstOrDefault()
		.GetCustomAttributes(typeof(DescriptionAttribute), inherit: false).FirstOrDefault()
		as DescriptionAttribute)?.Description ?? e.ToString() //defaults to enum name if no description
	});
}

cbProgrammingLanguages.DataSource = enumValuesAndDescriptions;

//Set DisplayMember and ValueMember to the appropriate properties (from the anonymous objects above)
cbProgrammingLanguages.DisplayMember = "EnumDescription"; 
cbProgrammingLanguages.ValueMember = "EnumValue";
Code language: C# (cs)

Note: This approach with ArrayList works no matter how you’re getting the enum type (hardcoded, from a generic type parameter, or from a reflected property type). This is because you don’t need to cast the Array object returned by Enum.GetValues().

I suggest using very explicit property names – hence EnumDescription and EnumValue.

This shows the enum descriptions in the ComboBox:

WinForms - ComboBox showing enum descriptions (C# and C++)

To get the enum value (i.e. ProgrammingLanguage.CSharp) that the user selected, you can either:

var coder = new Coder()
{
	Name = "Bob",
	Language = ProgrammingLanguage.CSharp
};

cbProgrammingLanguages.DataBindings.Add(nameof(ComboBox.SelectedValue), coder, nameof(Coder.Language));
Code language: C# (cs)

Notice that this uses SelectedValue, not SelectedItem.