Click here to Skip to main content
15,880,364 members
Articles / Desktop Programming
Tip/Trick

Binding Enum-Values to a ComboBox

Rate me:
Please Sign up or sign in to vote.
4.00/5 (5 votes)
15 Mar 2015CPOL1 min read 17.5K   115   12   7
Tidy, generic solution to bind Enums (with or without a DescriptionAttribute) to a ComboBox or other Controls

Introduction

The solution presented here provides a simple and tidy way to bind Enums to a ComboBox or (with only minor adjustments) to any other bindable control. If you decorated your Enum-members with a DescriptionAttribute, that description can be used as the DisplayMember for the Control-Binding, otherwise the name of the Enum-member can be used instead.

Background

The idea for this tip/trick originates from my answer to a recent question in CodeProject Q&A where in a comment it was suggested that I write it up as a tip/trick. The inquirer of the Q&A-question had troubles implementing a solution proposed to a question on Code Review (StackExchange) which is where the original code comes from (especially StackExchange-Member Jesse C. Slicer). I only claim credit for making it a generic solution (along with some other minor improvements) and packing it up into a tidy sample.

Using the Code

The sample uses these two Enum-definitions - one with, one without Description-Attributes:

C#
public enum AnimalOption
{
    [Description("flying animal")]
    Bird,
    [Description("best friend")]
    Dog,
    [Description("cuddly carnivore")]
    Cat
}

public enum ShapeOption
{
    Circle,
    Rectangle,
    Line
}

They get bound to ComboBoxes in the constructor of the Form. As you can see, it's done via a generic extension method to ComboBox that takes the Enum-Type as generic type argument and a DisplayMode-argument that tells whether it should look for Description-Attributes to use for the DisplayMember or use the name of the Enum-Member instead (ValueToString).

C#
public Form1()
{
    InitializeComponent();

    AnimalComboBox.BindEnum<AnimalOption>(DisplayMode.DescriptionAttribute);
    ShapeComboBox.BindEnum<ShapeOption>(DisplayMode.ValueToString);
}

The implementation of the extension method and its "helpers" is as follows:

C#
public class EnumBindingItem<TEnum>
{
    public string Description { get; private set; }
    public TEnum Value { get; set; } // setter needs to be public for the binding to work

    public EnumBindingItem(string description, TEnum value)
    {
        Description = description;
        Value = value;
    }
}

public enum DisplayMode
{
    DescriptionAttribute,
    ValueToString
}

public static class EnumBindingExtension
{
    public static void BindEnum<TEnum>(this ComboBox cbo, DisplayMode mode)
    {
        cbo.DataSource = Enum.GetValues(typeof(TEnum))
                                .Cast<TEnum>()
                                .Select(value => CreateEnumBindingItem(value, mode))
                                .OrderBy(item => item.Value)
                                .ToList();

        cbo.DisplayMember = "Description";
        cbo.ValueMember = "Value";
    }

    private static EnumBindingItem<TEnum> CreateEnumBindingItem<TEnum>(TEnum value, DisplayMode mode)
    {
        string description;

        if (mode == DisplayMode.DescriptionAttribute)
        {
            FieldInfo enumMember = typeof(TEnum).GetField(value.ToString());
            DescriptionAttribute attribute = (DescriptionAttribute)
                Attribute.GetCustomAttribute(enumMember, typeof(DescriptionAttribute));
            description = attribute.Description;
        }
        else
        {
            description = value.ToString();
        }

        return new EnumBindingItem<TEnum>(description, value);
    }
}

In the SelectedValueChanged-EventHandlers of the ComboBoxes, you can then easily get the selected Enum-value like this:

C#
private void AnimalComboBoxSelectedValueChanged(object sender, EventArgs e)
{
    AnimalOption selectedAnimal = ((EnumBindingItem<AnimalOption>)AnimalComboBox.SelectedItem).Value;

    AnimalSelectionLabel.Text = selectedAnimal.ToString();
}

private void ShapeComboBoxSelectedValueChanged(object sender, EventArgs e)
{
    ShapeOption selectedShape = ((EnumBindingItem<ShapeOption>)ShapeComboBox.SelectedItem).Value;

    ShapeSelectionLabel.Text = selectedShape.ToString();
}

I hope it's useful to you! Comments are welcome!

History

  • v1.1 - March 16, 2015
    • Incorporated the suggestion from Klaus Luedenscheidt and one of Sergey Alexandrovich Kryukov's suggestions. No functional changes.
  • v1.0 - March 15, 2015

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
SuggestionDisplayName vs Description Pin
Daniele Rota Nodari16-Mar-15 5:08
Daniele Rota Nodari16-Mar-15 5:08 
Hi.

I suggest to use DisplayNameAttribute instead of DescriptionAttribute: within my own projects, I associate both attibutes to enum fields, where the first one holds short texts and the second longest ones, like tooltip bodies.

Regards,
Daniele.
GeneralRe: DisplayName vs Description Pin
manchanx16-Mar-15 5:29
professionalmanchanx16-Mar-15 5:29 
GeneralMy vote of 4 Pin
Klaus Luedenscheidt15-Mar-15 20:05
Klaus Luedenscheidt15-Mar-15 20:05 
GeneralRe: My vote of 4 Pin
manchanx16-Mar-15 1:12
professionalmanchanx16-Mar-15 1:12 
GeneralRe: My vote of 4 Pin
Klaus Luedenscheidt16-Mar-15 1:57
Klaus Luedenscheidt16-Mar-15 1:57 
GeneralMy vote of 4 Pin
Sergey Alexandrovich Kryukov15-Mar-15 13:50
mvaSergey Alexandrovich Kryukov15-Mar-15 13:50 
GeneralRe: My vote of 4 Pin
manchanx15-Mar-15 14:12
professionalmanchanx15-Mar-15 14:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.