Binding an enum to a WinForms combo box, and then setting it

C#.NetWinformsComboboxEnums

C# Problem Overview


a lot of people have answered the question of how to bind an enum to a combo box in WinForms. Its like this:

comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));

But that is pretty useless without being able to set the actual value to display.

I have tried:

comboBox1.SelectedItem = MyEnum.Something; // Does not work. SelectedItem remains null

I have also tried:

comboBox1.SelectedIndex = Convert.ToInt32(MyEnum.Something); // ArgumentOutOfRangeException, SelectedIndex remains -1

Does anyone have any ideas how to do this?

C# Solutions


Solution 1 - C#

The Enum

public enum Status { Active = 0, Canceled = 3 }; 

Setting the drop down values from it

cbStatus.DataSource = Enum.GetValues(typeof(Status));

Getting the enum from the selected item

Status status; 
Enum.TryParse<Status>(cbStatus.SelectedValue.ToString(), out status); 

Solution 2 - C#

To simplify:

First Initialize this command: (e.g. after InitalizeComponent())

yourComboBox.DataSource =  Enum.GetValues(typeof(YourEnum));

To retrieve selected item on combobox:

YourEnum enum = (YourEnum) yourComboBox.SelectedItem;

If you want to set value for the combobox:

yourComboBox.SelectedItem = YourEnem.Foo;

Solution 3 - C#

The code

comboBox1.SelectedItem = MyEnum.Something;

is ok, the problem must reside in the DataBinding. DataBinding assignments occur after the constructor, mainly the first time the combobox is shown. Try to set the value in the Load event. For example, add this code:

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    comboBox1.SelectedItem = MyEnum.Something;
}

And check if it works.

Solution 4 - C#

Try:

comboBox1.SelectedItem = MyEnum.Something;

EDITS:

Whoops, you've tried that already. However, it worked for me when my comboBox was set to be a DropDownList.

Here is my full code which works for me (with both DropDown and DropDownList):

public partial class Form1 : Form
{
    public enum BlahEnum
    { 
        Red,
        Green,
        Blue,
        Purple
    }

    public Form1()
    {
        InitializeComponent();

        comboBox1.DataSource = Enum.GetValues(typeof(BlahEnum));

    }

    private void button1_Click(object sender, EventArgs e)
    {
        comboBox1.SelectedItem = BlahEnum.Blue;
    }
}

Solution 5 - C#

Let's say you have the following enum

public enum Numbers {Zero = 0, One, Two};

You need to have a struct to map those values to a string:

public struct EntityName
{
    public Numbers _num;
    public string _caption;

    public EntityName(Numbers type, string caption)
    {
        _num = type;
        _caption = caption;
    }

    public Numbers GetNumber() 
    {
        return _num;
    }

    public override string ToString()
    {
        return _caption;
    }
}

Now return an array of objects with all the enums mapped to a string:

public object[] GetNumberNameRange()
{
    return new object[]
    {
        new EntityName(Number.Zero, "Zero is chosen"),
        new EntityName(Number.One, "One is chosen"),
        new EntityName(Number.Two, "Two is chosen")
    };
}

And use the following to populate your combo box:

ComboBox numberCB = new ComboBox();
numberCB.Items.AddRange(GetNumberNameRange());

Create a function to retrieve the enum type just in case you want to pass it to a function

public Numbers GetConversionType() 
{
    EntityName type = (EntityName)numberComboBox.SelectedItem;
    return type.GetNumber();           
}

and then you should be ok :)

Solution 6 - C#

This is probably never going to be seen among all the other responses, but this is the code I came up with, this has the benefit of using the DescriptionAttribute if it exists, but otherwise using the name of the enum value itself.

I used a dictionary because it has a ready made key/value item pattern. A List<KeyValuePair<string,object>> would also work and without the unnecessary hashing, but a dictionary makes for cleaner code.

I get members that have a MemberType of Field and that are literal. This creates a sequence of only members that are enum values. This is robust since an enum cannot have other fields.

public static class ControlExtensions
{
    public static void BindToEnum<TEnum>(this ComboBox comboBox)
    {
        var enumType = typeof(TEnum);

        var fields = enumType.GetMembers()
                              .OfType<FieldInfo>()
                              .Where(p => p.MemberType == MemberTypes.Field)
                              .Where(p => p.IsLiteral)
                              .ToList();

        var valuesByName = new Dictionary<string, object>();

        foreach (var field in fields)
        {
            var descriptionAttribute = field.GetCustomAttribute(typeof(DescriptionAttribute), false) as DescriptionAttribute;

            var value = (int)field.GetValue(null);
            var description = string.Empty;

            if (!string.IsNullOrEmpty(descriptionAttribute?.Description))
            {
                description = descriptionAttribute.Description;
            }
            else
            {
                description = field.Name;
            }

            valuesByName[description] = value;
        }

        comboBox.DataSource = valuesByName.ToList();
        comboBox.DisplayMember = "Key";
        comboBox.ValueMember = "Value";
    }


}

Solution 7 - C#

Try this:

// fill list
MyEnumDropDownList.DataSource = Enum.GetValues(typeof(MyEnum));

// binding
MyEnumDropDownList.DataBindings.Add(new Binding("SelectedValue", StoreObject, "StoreObjectMyEnumField"));

StoreObject is my object example with StoreObjectMyEnumField property for store MyEnum value.

Solution 8 - C#

 public static void FillByEnumOrderByNumber<TEnum>(this System.Windows.Forms.ListControl ctrl, TEnum enum1, bool showValueInDisplay = true) where TEnum : struct
    {
        if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");

        var values = from TEnum enumValue in Enum.GetValues(typeof(TEnum))
                     select
                        new
                         KeyValuePair<TEnum, string>(   (enumValue), enumValue.ToString());

        ctrl.DataSource = values
            .OrderBy(x => x.Key)
            
            .ToList();

        ctrl.DisplayMember = "Value";
        ctrl.ValueMember = "Key";

        ctrl.SelectedValue = enum1;
    }
    public static void  FillByEnumOrderByName<TEnum>(this System.Windows.Forms.ListControl ctrl, TEnum enum1, bool showValueInDisplay = true  ) where TEnum : struct
    {
        if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");

        var values = from TEnum enumValue in Enum.GetValues(typeof(TEnum))
                     select 
                        new 
                         KeyValuePair<TEnum,string> ( (enumValue),  enumValue.ToString()  );
        
        ctrl.DataSource = values
            .OrderBy(x=>x.Value)
            .ToList();
        
        ctrl.DisplayMember = "Value";
        ctrl.ValueMember = "Key";

        ctrl.SelectedValue = enum1;
    }

Solution 9 - C#

This worked for me:

comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));
comboBox1.SelectedIndex = comboBox1.FindStringExact(MyEnum.something.ToString());

Solution 10 - C#

this is the solution to load item of enum in combobox :

comboBox1.Items.AddRange( Enum.GetNames(typeof(Border3DStyle)));

And then use the enum item as text :

toolStripStatusLabel1.BorderStyle = (Border3DStyle)Enum.Parse(typeof(Border3DStyle),comboBox1.Text);

Solution 11 - C#

Based on the answer from @Amir Shenouda I end up with this:

Enum's definition:

public enum Status { Active = 0, Canceled = 3 }; 

Setting the drop down values from it:

cbStatus.DataSource = Enum.GetValues(typeof(Status));

Getting the enum from the selected item:

Status? status = cbStatus.SelectedValue as Status?;

Solution 12 - C#

public Form1()
{
    InitializeComponent();
    comboBox.DataSource = EnumWithName<SearchType>.ParseEnum();
    comboBox.DisplayMember = "Name";
}

public class EnumWithName<T>
{
    public string Name { get; set; }
    public T Value { get; set; }

    public static EnumWithName<T>[] ParseEnum()
    {
        List<EnumWithName<T>> list = new List<EnumWithName<T>>();

        foreach (object o in Enum.GetValues(typeof(T)))
        {
            list.Add(new EnumWithName<T>
            {
                Name = Enum.GetName(typeof(T), o).Replace('_', ' '),
                Value = (T)o
            });
        }

        return list.ToArray();
    }
}

public enum SearchType
{
    Value_1,
    Value_2
}

Solution 13 - C#

None of these worked for me, but this did (and it had the added benefit of being able to have a better description for the name of each enum). I'm not sure if it's due to .net updates or not, but regardless I think this is the best way. You'll need to add a reference to:

using System.ComponentModel;

enum MyEnum
{
    [Description("Red Color")]
    Red = 10,
    [Description("Blue Color")]
    Blue = 50
}

....

    private void LoadCombobox()
    {
        cmbxNewBox.DataSource = Enum.GetValues(typeof(MyEnum))
            .Cast<Enum>()
            .Select(value => new
            {
                (Attribute.GetCustomAttribute(value.GetType().GetField(value.ToString()), typeof(DescriptionAttribute)) as DescriptionAttribute).Description,
                value
            })
            .OrderBy(item => item.value)
            .ToList();
        cmbxNewBox.DisplayMember = "Description";
        cmbxNewBox.ValueMember = "value";
    }

Then when you want to access the data use these two lines:

        Enum.TryParse<MyEnum>(cmbxNewBox.SelectedValue.ToString(), out MyEnum proc);
        int nValue = (int)proc;

Solution 14 - C#

I use the following helper method, which you can bind to your list.

    ''' <summary>
    ''' Returns enumeration as a sortable list.
    ''' </summary>
    ''' <param name="t">GetType(some enumeration)</param>
    Public Shared Function GetEnumAsList(ByVal t As Type) As SortedList(Of String, Integer)

        If Not t.IsEnum Then
            Throw New ArgumentException("Type is not an enumeration.")
        End If

        Dim items As New SortedList(Of String, Integer)
        Dim enumValues As Integer() = [Enum].GetValues(t)
        Dim enumNames As String() = [Enum].GetNames(t)

        For i As Integer = 0 To enumValues.GetUpperBound(0)
            items.Add(enumNames(i), enumValues(i))
        Next

        Return items

    End Function

Solution 15 - C#

Convert the enum to a list of string and add this to the comboBox

comboBox1.DataSource = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();

Set the displayed value using selectedItem

comboBox1.SelectedItem = SomeEnum.SomeValue;

Solution 16 - C#

    public enum Colors
    {
        Red = 10,
        Blue = 20,
        Green = 30,
        Yellow = 40,
    }

comboBox1.DataSource = Enum.GetValues(typeof(Colors));

Full Source...Binding an enum to Combobox

Solution 17 - C#

You can use a extension method

 public static void EnumForComboBox(this ComboBox comboBox, Type enumType)
 {
     var memInfo = enumType.GetMembers().Where(a => a.MemberType == MemberTypes.Field).ToList();
     comboBox.Items.Clear();
     foreach (var member in memInfo)
     {
         var myAttributes = member.GetCustomAttribute(typeof(DescriptionAttribute), false);
         var description = (DescriptionAttribute)myAttributes;
         if (description != null)
         {
             if (!string.IsNullOrEmpty(description.Description))
             {
                 comboBox.Items.Add(description.Description);
                 comboBox.SelectedIndex = 0;
                 comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
             }
         }   
     }
 }

How to use ... Declare enum

using System.ComponentModel;

public enum CalculationType
{
    [Desciption("LoaderGroup")]
    LoaderGroup,
    [Description("LadingValue")]
    LadingValue,
    [Description("PerBill")]
    PerBill
}

This method show description in Combo box items

combobox1.EnumForComboBox(typeof(CalculationType));

Solution 18 - C#

You could use the "FindString.." functions:

Public Class Form1
    Public Enum Test
        pete
        jack
        fran
        bill
    End Enum
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ComboBox1.DataSource = [Enum].GetValues(GetType(Test))
        ComboBox1.SelectedIndex = ComboBox1.FindStringExact("jack")
        ComboBox1.SelectedIndex = ComboBox1.FindStringExact(Test.jack.ToString())
        ComboBox1.SelectedIndex = ComboBox1.FindStringExact([Enum].GetName(GetType(Test), Test.jack))
        ComboBox1.SelectedItem = Test.bill
    End Sub
End Class

Solution 19 - C#

comboBox1.SelectedItem = MyEnum.Something;

should work just fine ... How can you tell that SelectedItem is null?

Solution 20 - C#

You can use a list of KeyValuePair values as the datasource for the combobox. You will need a helper method where you can specify the enum type and it returns IEnumerable> where int is the value of enum and string is the name of the enum value. In your combobox, set, DisplayMember property to 'Key' and ValueMember property to 'Value'. Value and Key are public properties of KeyValuePair structure. Then when you set SelectedItem property to an enum value like you are doing, it should work.

Solution 21 - C#

At the moment I am using the Items property rather than the DataSource, it means I have to call Add for each enum value, but its a small enum, and its temporary code anyway.

Then I can just do the Convert.ToInt32 on the value and set it with SelectedIndex.

Temporary solution, but YAGNI for now.

Cheers for the ideas, I will probably use them when I do the proper version after getting a round of customer feedback.

Solution 22 - C#

Old question perhaps here but I had the issue and the solution was easy and simple, I found this http://www.c-sharpcorner.com/UploadFile/mahesh/1220/

It makes use of the databining and works nicely so check it out.

Solution 23 - C#

comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));

comboBox1.SelectedIndex = (int)MyEnum.Something;

comboBox1.SelectedIndex = Convert.ToInt32(MyEnum.Something);

Both of these work for me are you sure there isn't something else wrong?

Solution 24 - C#

Generic method for setting a enum as datasource for drop downs

Display would be name. Selected value would be Enum itself

public IList<KeyValuePair<string, T>> GetDataSourceFromEnum<T>() where T : struct,IConvertible
    {
        IList<KeyValuePair<string, T>> list = new BindingList<KeyValuePair<string, T>>();
        foreach (string value in Enum.GetNames(typeof(T)))
        {
            list.Add(new KeyValuePair<string, T>(value, (T)Enum.Parse(typeof(T), value)));
        }
        return list;
    }

Solution 25 - C#

That was always a problem. if you have a Sorted Enum, like from 0 to ...

public enum Test
      one
      Two
      Three
 End

you can bind names to combobox and instead of using .SelectedValue property use .SelectedIndex

   Combobox.DataSource = System.Enum.GetNames(GetType(test))

and the

Dim x as byte = 0
Combobox.Selectedindex=x

Solution 26 - C#

In Framework 4 you can use the following code:

To bind MultiColumnMode enum to combobox for example:

cbMultiColumnMode.Properties.Items.AddRange(typeof(MultiColumnMode).GetEnumNames());

and to get selected index:

MultiColumnMode multiColMode = (MultiColumnMode)cbMultiColumnMode.SelectedIndex;

note: I use DevExpress combobox in this example, you can do the same in Win Form Combobox

Solution 27 - C#

A little late to this party ,

The SelectedValue.ToString() method should pull in the DisplayedName . However this article DataBinding Enum and also With Descriptions shows a handy way to not only have that but instead you can add a custom description attribute to the enum and use it for your displayed value if you preferred. Very simple and easy and about 15 lines or so of code (unless you count the curly braces) for everything.

It is pretty nifty code and you can make it an extension method to boot ...

Solution 28 - C#

only use casting this way:

if((YouEnum)ComboBoxControl.SelectedItem == YouEnum.Español)
{
   //TODO: type you code here
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTony MilettoView Question on Stackoverflow
Solution 1 - C#Amir ShenoudaView Answer on Stackoverflow
Solution 2 - C#dr.CrowView Answer on Stackoverflow
Solution 3 - C#jmserveraView Answer on Stackoverflow
Solution 4 - C#reinView Answer on Stackoverflow
Solution 5 - C#ncoder83View Answer on Stackoverflow
Solution 6 - C#JordanView Answer on Stackoverflow
Solution 7 - C#Pavel ŠubíkView Answer on Stackoverflow
Solution 8 - C#Mickey PerlsteinView Answer on Stackoverflow
Solution 9 - C#ShreyView Answer on Stackoverflow
Solution 10 - C#Haider Ali WajihiView Answer on Stackoverflow
Solution 11 - C#TarcView Answer on Stackoverflow
Solution 12 - C#ProteuxView Answer on Stackoverflow
Solution 13 - C#ZonusView Answer on Stackoverflow
Solution 14 - C#ScottEView Answer on Stackoverflow
Solution 15 - C#Stijn BollenView Answer on Stackoverflow
Solution 16 - C#caronjudithView Answer on Stackoverflow
Solution 17 - C#Morteza NajafianView Answer on Stackoverflow
Solution 18 - C#Abe LincolnView Answer on Stackoverflow
Solution 19 - C#bruno condeView Answer on Stackoverflow
Solution 20 - C#Mehmet ArasView Answer on Stackoverflow
Solution 21 - C#Tony MilettoView Answer on Stackoverflow
Solution 22 - C#JohanView Answer on Stackoverflow
Solution 23 - C#claybo.the.invincibleView Answer on Stackoverflow
Solution 24 - C#RahulView Answer on Stackoverflow
Solution 25 - C#FarhadView Answer on Stackoverflow
Solution 26 - C#Sherif HassaneenView Answer on Stackoverflow
Solution 27 - C#StixView Answer on Stackoverflow
Solution 28 - C#Victor GomezView Answer on Stackoverflow