Click here to Skip to main content
15,880,608 members
Articles / Programming Languages / C#
Tip/Trick

Using human readable enum values in a ComboBox

Rate me:
Please Sign up or sign in to vote.
4.83/5 (16 votes)
31 Jan 2012CPOL 51.3K   15   7
Sometimes, all I want is a control which allows the user to select one of several options, and tell me which one - ideally as a handy enum value. This shows a simple method which allows this.
If you have a range of values in your program, and you want the user to select one of them, the most useful (to him) is a human readable string. Unfortunately, the most useful (to you) is an enum value, and the most commonly available is the enum value name. Which means that the value name has to be carefully selected to fit both the human readable requirement, and the compiler requirement of "no special characters". Such as space.

The alternative is to load a combo box with a set of fixed strings, and then decode them into your enum values later. Which is something I avoid, as I am sure to miss one when I add options to the enum.

This Tip presents a way to fill a ComboBox with human readable strings, and tie them to enum values.

Create your enum, and give human readable Description attributes:
C#
public enum MyEnum
{
    [Description("The first")]
    the1st = 1,
    [Description("The second one")]
    the2nd = 8000,
    [Description("Another one!")]
    final = -1,
}
Then include this static method in your code:
C#
/// <summary>
/// Set the combo box to the enum values.
/// </summary>
/// <remarks>
/// If you use the Description attribute on your enum elements, that will
/// be used as the human readable ComboBox text.
/// If you don't, the enum element name will be used.
/// </remarks>
/// <example>
///         public enum MyEnum
///            {
///            [Description("The first")]
///            the1st = 1,
///            [Description("The second one")]
///            the2nd = 8000,
///            [Description("Another one!")]
///            final = -1,
///            }
///         ...
///         SetEnumValues(myComboBox, typeof(MyEnum));
/// </example>
/// <exception cref="ArgumentException">
/// Thrown if the Type supplied is not an Enum
/// </exception>
/// <param name="cb">ComboBox to set</param>
/// <param name="t">Type of enum to set values from</param>
public static void SetEnumValues(ComboBox cb, Type t)
    {
    if (!t.IsEnum)
        {
        throw new ArgumentException("Only Enum types can be set");
        }
    List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>();
    foreach (int i in Enum.GetValues(t))
        {
        string name = Enum.GetName(t, i);
        string desc = name;
        FieldInfo fi = t.GetField(name);
        // Get description for enum element
        DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
        if (attributes.Length > 0)
            {
            string s = attributes[0].Description;
            if (!string.IsNullOrEmpty(s))
                {
                desc = s;
                }
            }
        list.Add(new KeyValuePair<string, int>(desc, i));
        }
    // NOTE: It is very important that DisplayMember and ValueMember are set before DataSource.
    //       If you do, this works fine, and the SelectedValue of the ComboBox will be an int
    //       version of the Enum.
    //       If you don't, it will be a KeyValuePair.
    cb.DisplayMember = "Key"; 
    cb.ValueMember = "Value";
    cb.DataSource = list;
}
Call the method to set the values into your ComboBox:
C#
myComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
SetEnumValues(myComboBox, typeof(MyEnum));

The CombBox will now show the values:
The first
The second one
Another one!
You can now use the values as you wish in your ComboBox events:
C#
private void myComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    Console.WriteLine(myComboBox.Text);
    Console.WriteLine(myComboBox.SelectedValue);
    MyEnum me = (MyEnum)myComboBox.SelectedValue;
    Console.WriteLine(me.ToString());
}
Will display:
The first
1
the1st

The second one
8000
the2nd

Another one!
-1
final

License

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


Written By
CEO
Wales Wales
Born at an early age, he grew older. At the same time, his hair grew longer, and was tied up behind his head.
Has problems spelling the word "the".
Invented the portable cat-flap.
Currently, has not died yet. Or has he?

Comments and Discussions

 
QuestionGreat Solution! But I have a Question... Pin
BigTex654-May-12 8:09
BigTex654-May-12 8:09 
AnswerRe: Great Solution! But I have a Question... Pin
OriginalGriff4-May-12 8:50
mveOriginalGriff4-May-12 8:50 
Generalhow about multi-lingual support? Pin
Huisheng Chen3-Feb-12 14:14
Huisheng Chen3-Feb-12 14:14 
GeneralReason for my vote of 2 Friendly enum names are good, but ha... Pin
jim lahey1-Feb-12 5:49
jim lahey1-Feb-12 5:49 
GeneralThat's the worst implementation to this topic I've ever seen... Pin
springy7625-Jan-12 0:30
springy7625-Jan-12 0:30 
GeneralRe: Where's yours? Pin
dandy7225-Jan-12 12:17
dandy7225-Jan-12 12:17 
GeneralReason for my vote of 5 I like it. Pin
fjdiewornncalwe24-Jan-12 9:04
professionalfjdiewornncalwe24-Jan-12 9:04 

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.