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:
To get the enum value (i.e. ProgrammingLanguage.CSharp) that the user selected, you can either:
- Check ComboBox.SelectedValue in the code.
- Or bind an object’s enum property to ComboBox.SelectedValue (NOT SelectedItem!), like this:
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.