将枚举绑定到WinForms组合框,然后进行设置

112 .net c# enums combobox winforms

很多人都回答了如何将枚举绑定到WinForms中的组合框的问题.就像这样:

comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));
Run Code Online (Sandbox Code Playgroud)

但是如果不能设置要显示的实际值,那就没用了.

我试过了:

comboBox1.SelectedItem = MyEnum.Something; // Does not work. SelectedItem remains null
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

comboBox1.SelectedIndex = Convert.ToInt32(MyEnum.Something); // ArgumentOutOfRangeException, SelectedIndex remains -1
Run Code Online (Sandbox Code Playgroud)

有没有人有任何想法如何做到这一点?

小智 150

恩欧姆

public enum Status { Active = 0, Canceled = 3 }; 
Run Code Online (Sandbox Code Playgroud)

设置下拉值

cbStatus.DataSource = Enum.GetValues(typeof(Status));
Run Code Online (Sandbox Code Playgroud)

从所选项目中获取枚举

Status status; 
Enum.TryParse<Status>(cbStatus.SelectedValue.ToString(), out status); 
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这对我有用.请记住,tryparse是一个.net 4.0语句. (5认同)
  • 为什么使用TryParse而不是Parse?... var status(Status)Enum.Parse(typeof(Status),cbStatus.SelectedValue.ToString()); ...您将枚举绑定到组合框,因此您知道该值必须是有效的枚举值,如果它不会出现问题,你可能想要一个例外. (5认同)
  • 这正是OP不想使用的方式.问题是用户在每个值的代码中都显示了名称,这些值经过重构并且大多数时候都不是用户友好的. (3认同)

dr.*_*row 32

简化:

首先初始化此命令:(例如之后InitalizeComponent())

yourComboBox.DataSource =  Enum.GetValues(typeof(YourEnum));
Run Code Online (Sandbox Code Playgroud)

要在组合框上检索所选项目:

YourEnum enum = (YourEnum) yourComboBox.SelectedItem;
Run Code Online (Sandbox Code Playgroud)

如果要为组合框设置值:

yourComboBox.SelectedItem = YourEnem.Foo;
Run Code Online (Sandbox Code Playgroud)

  • 只要Display值与Value成员相同,就可以使用,否则不行. (2认同)

jms*_*era 15

代码

comboBox1.SelectedItem = MyEnum.Something;
Run Code Online (Sandbox Code Playgroud)

没问题,问题必须存在于DataBinding中.DataBinding赋值发生在构造函数之后,主要是第一次显示组合框.尝试在Load事件中设置值.例如,添加以下代码:

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    comboBox1.SelectedItem = MyEnum.Something;
}
Run Code Online (Sandbox Code Playgroud)

并检查它是否有效.


rei*_*ein 12

尝试:

comboBox1.SelectedItem = MyEnum.Something;
Run Code Online (Sandbox Code Playgroud)

EDITS:

哎呀,你已经尝试过了.但是,当我的comboBox设置为DropDownList时,它对我有用.

这是我的完整代码,适用于我(使用DropDown和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;
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 11

假设你有以下枚举

public enum Numbers {Zero = 0, One, Two};
Run Code Online (Sandbox Code Playgroud)

您需要有一个结构来将这些值映射到字符串:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在返回一个对象数组,其中所有枚举都映射到一个字符串:

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")
    };
}
Run Code Online (Sandbox Code Playgroud)

并使用以下内容填充您的组合框:

ComboBox numberCB = new ComboBox();
numberCB.Items.AddRange(GetNumberNameRange());
Run Code Online (Sandbox Code Playgroud)

创建一个函数来检索枚举类型,以防您想将它传递给函数

public Numbers GetConversionType() 
{
    EntityName type = (EntityName)numberComboBox.SelectedItem;
    return type.GetNumber();           
}
Run Code Online (Sandbox Code Playgroud)

然后你应该没事:)


Jor*_*dan 9

这可能永远不会在所有其他响应中看到,但这是我想出的代码,这样做的好处是使用 if DescriptionAttributeit是否存在,但否则使用枚举值本身的名称。

我使用字典是因为它有一个现成的键/值项模式。AList<KeyValuePair<string,object>>也可以工作,并且不需要不必要的散列,但是字典可以使代码更清晰。

我得到的成员有一个MemberTypeofField并且是字面意思。这将创建一个仅包含枚举值成员的序列。这是很强大的,因为枚举不能有其他字段。

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";
    }


}
Run Code Online (Sandbox Code Playgroud)


小智 5

尝试这个:

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

// binding
MyEnumDropDownList.DataBindings.Add(new Binding("SelectedValue", StoreObject, "StoreObjectMyEnumField"));
Run Code Online (Sandbox Code Playgroud)

StoreObject是我的对象示例,具有StoreMyEnum值的StoreObjectMyEnumField属性。

  • 这是迄今为止最好的方法,但事实上,它对我不起作用。我必须使用“SelectedItem”而不是“SelectedValue” (2认同)

Mic*_*ein 5

 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;
    }
Run Code Online (Sandbox Code Playgroud)