Reputation:
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?
Upvotes: 142
Views: 241271
Reputation: 1563
To simplify:
First Initialize this command: (e.g. after InitalizeComponent()
)
yourComboBox.DataSource = Enum.GetValues(typeof(YourEnum));
To retrieve selected item on combobox:
YourEnum selectedValue = (YourEnum) yourComboBox.SelectedItem;
If you want to set value for the combobox:
yourComboBox.SelectedItem = YourEnum.Foo;
Upvotes: 57
Reputation: 63
This worked for me:
comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));
comboBox1.SelectedIndex = comboBox1.FindStringExact(MyEnum.something.ToString());
Upvotes: 4
Reputation: 9911
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";
}
}
Upvotes: 12
Reputation: 2908
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;
Upvotes: 2
Reputation: 11
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));
Upvotes: 1
Reputation: 1
only use casting this way:
if((YouEnum)ComboBoxControl.SelectedItem == YouEnum.Español)
{
//TODO: type you code here
}
Upvotes: 0
Reputation: 6682
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.
Upvotes: 15
Reputation: 183
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 :)
Upvotes: 13
Reputation: 3332
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?;
Upvotes: 3
Reputation: 495
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 ...
Upvotes: 0
Reputation: 11
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
Upvotes: 0
Reputation: 19
public enum Colors
{
Red = 10,
Blue = 20,
Green = 30,
Yellow = 40,
}
comboBox1.DataSource = Enum.GetValues(typeof(Colors));
Full Source...Binding an enum to Combobox
Upvotes: 1
Reputation: 4124
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;
}
Upvotes: 5
Reputation: 91
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.
Upvotes: 9
Reputation: 33
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
Upvotes: 0
Reputation: 1
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;
}
Upvotes: 0
Reputation: 396
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;
Upvotes: 1
Reputation: 2185
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);
Upvotes: 188
Reputation: 2795
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);
Upvotes: 3
Reputation: 235
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?
Upvotes: 0
Reputation: 753
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.
Upvotes: 0
Reputation: 213
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
}
Upvotes: 2
Reputation: 21630
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
Upvotes: 1
Reputation:
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.
Upvotes: 0
Reputation: 5374
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.
Upvotes: 0
Reputation:
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
Upvotes: 0
Reputation: 48255
comboBox1.SelectedItem = MyEnum.Something;
should work just fine ... How can you tell that SelectedItem
is null?
Upvotes: 0
Reputation: 33465
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;
}
}
Upvotes: 14