Home > Software engineering >  Cast combobox SelectedValue to Enum type - WinForm
Cast combobox SelectedValue to Enum type - WinForm

Time:11-13

Hey guy's I wana cast combobox SelectedValue to Enum type, but selected value item is a list like {Title, Value}; Title is "description attribute of enum items" and Value is "enum items".

var EnumItems = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Select(item =>
                   new
                   {
                       Text = item.GetEnumName(),
                       Value = item
                   }).ToList();
            MyCombo.DataSource = EnumItems;
            MyCombo.DisplayMember = "Text";
            MyCombo.ValueMember = "Value";

GetEnumName() Method:

public static string GetEnumName(this System.Enum myEnum)
        {
            var enumDisplayName = myEnum.GetType().GetMember(myEnum.ToString()).FirstOrDefault();
            if (enumDisplayName != null)
            {
                //return enumDisplayName.GetCustomAttribute<DescriptionAttribute>()?.Get();
                return string.Format("{0}", (Attribute.GetCustomAttribute(myEnum.GetType().GetField(myEnum.ToString()), typeof(DescriptionAttribute)) as DescriptionAttribute).Description, false);
            }

            return "";
        }

I try this way to cast:

var getEnum = (MyEnum)Enum.Parse(typeof(MyEnum), MyCombo.SelectedValue.ToString());

but this way return:

System.ArgumentException: 'Requested value '{ Text = enumDescriptionText, Value = enumValue }' was not found.'

Have you a solution for solve this problem?

CodePudding user response:

When you setting your data source, you creating anonymous type 'a with Text and Value properties:

comboBox1.DataSource = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Select(item => new
{
    Text = item.GetEnumDescription(),
    Value = item
}).ToList();

so it is at result a List<'a>.

When you trying to retrieve selected in ComboBox value/item, it would be item of anonymous type 'a too, so you can't cast it to MyEnum explicitly.

The solution may be in usage of dynamics, which can be also of your anonymous type and at runtime has Text and Value properties:

private void OnComboBoxSelectedValueChanged(object sender, EventArgs e)
{
    dynamic selectedItem = comboBox1.SelectedItem;

    if (selectedItem != null)
    {
        MyEnum enumItem = (MyEnum)selectedItem.Value;
        string itemDescription = selectedItem.Text;

        _ = MessageBox.Show(string.Format("Enum item: {0}\nItem description: {1}", enumItem, itemDescription));
    }
}

I have this result:

enter image description here

My enum looks like:

enum MyEnum
{
    [Description("My 1st item")]
    MyItem1,
    [Description("My 2nd item")]
    MyItem2,
    [Description("My 3rd item")]
    MyItem3
}

Mine .GetEnumDescription() is rewrited yours .GetEnumName() in ternary style:

public static class EnumExtensions
{
    public static string GetEnumDescription(this Enum enumValue) =>
        enumValue.GetType().GetMember(nameof(enumValue)).FirstOrDefault() is MemberInfo
        ? $"{(Attribute.GetCustomAttribute(enumValue.GetType().GetField(nameof(enumValue)), typeof(DescriptionAttribute)) as DescriptionAttribute)?.Description}"
        : string.Empty;
}
  • Related