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

许多人已经回答了如何在 WinForms 中将枚举绑定到组合框的问题。事情是这样的:

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

但是,如果不能设置要显示的实际值,那么这种方法就相当无用。

我试过了:

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

我也试过:

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

有人知道怎么做吗?

218697 次浏览

试试:

comboBox1.SelectedItem = MyEnum.Something;

编辑:

哎呀,你已经尝试过了。但是,当我的 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;
}
}

您可以使用“ FindString. .”函数:

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
comboBox1.SelectedItem = MyEnum.Something;

应该工作正常... 你怎么能告诉 SelectedItem是空的?

可以使用 KeyValuePair 值列表作为组合框的数据源。您将需要一个 helper 方法,其中您可以指定枚举类型,并且它返回 IEnumable > ,其中 int 是枚举的值,string 是枚举值的名称。在组合框中,将 DisplayMember 属性设置为“ Key”,将 ValueMember 属性设置为“ Value”。Value 和 Key 是 KeyValuePair 结构的公共属性。然后,当您像现在这样将 SelectedItem 属性设置为枚举值时,它应该可以工作。

目前我使用 Items 属性而不是 DataSource,这意味着我必须为每个枚举值调用 Add,但它是一个小枚举,而且它还有临时代码。

然后我可以对值执行 Convert.ToInt32并用 SelectedIndex 设置它。

暂时的解决方案,但 YAGNI 现在。

干杯的想法,我可能会使用他们当我做了正确的版本后,得到一轮客户反馈。

密码

comboBox1.SelectedItem = MyEnum.Something;

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

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

看看有没有用。

我使用以下 helper 方法,您可以将其绑定到列表。

    ''' <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

假设您有以下枚举

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

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

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

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

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

并使用以下命令填充组合框:

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

创建一个函数来检索枚举类型,以防需要将其传递给函数

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

然后你就会没事了:)

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
}

老问题也许在这里,但我有这个问题和解决方案是容易和简单的,我发现这个 http://www.c-sharpcorner.com/UploadFile/mahesh/1220/

它利用了数据库,并且工作得很好,所以请检查它。

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


comboBox1.SelectedIndex = (int)MyEnum.Something;


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

这些都是我的工作,你确定没有别的问题吗?

这就是解决办法 在组合框中加载枚举项:

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

然后使用枚举项作为文本:

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

Enum

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

从中设置下拉值

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

从选定项获取枚举

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

将枚举转换为字符串列表并将其添加到 comboBox

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

使用 selectedItem 设置显示的值

comboBox1.SelectedItem = SomeEnum.SomeValue;

将枚举设置为下拉列表数据源的通用方法

显示就是名字。 选择的值是 Enum 本身

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

这一直是个问题。 如果您有一个排序枚举,比如从0到..。

public enum Test
one
Two
Three
End

您可以将名称绑定到 combobox,并且不使用 .SelectedValue属性,而使用 .SelectedIndex

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

还有

Dim x as byte = 0
Combobox.Selectedindex=x

试试这个:

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


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

StoreObject 是我的对象示例,StoreObjectMyEnumField 属性用于存储 MyEnum 值。

 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;
}
    public enum Colors
{
Red = 10,
Blue = 20,
Green = 30,
Yellow = 40,
}


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

完整来源... 将枚举绑定到 Combobox

在框架4中,您可以使用以下代码:

例如,将 MultiColumnMode 枚举绑定到 combobox:

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

并获得选定的索引:

MultiColumnMode multiColMode = (MultiColumnMode)cbMultiColumnMode.SelectedIndex;

注意: 我在这个例子中使用 DevExpress 组合框,你可以在 Win Form 组合框中做同样的事情

这个派对有点晚了,

SelectedValue.ToString ()方法应该拉入 DisplayedName。 但是,本文 数据绑定枚举和说明展示了一种方便的方法,不仅可以实现这一点,还可以向枚举添加一个自定义描述属性,如果愿意,可以将其用于显示的值。非常简单,大约15行左右的代码(除非你算上大括号)。

这是相当漂亮的代码,你可以使它成为一个扩展方法来引导..。

简单来说:

首先初始化这个命令: (例如,在 InitalizeComponent()之后)

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

在组合框中检索选定项:

YourEnum enum = (YourEnum) yourComboBox.SelectedItem;

如果要为组合框设置值:

yourComboBox.SelectedItem = YourEnem.Foo;

根据@Amir Shenouda 的回答,我得出以下结论:

Enum 的定义:

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

从中设置下拉值:

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

从选定项获取枚举:

Status? status = cbStatus.SelectedValue as Status?;

只能这样施法:

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

可以使用扩展方法

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

如何使用..。 声明 enum

using System.ComponentModel;


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

此方法在组合框项中显示说明

combobox1.EnumForComboBox(typeof(CalculationType));

这些方法对我来说都不管用,但是这个方法管用(它还有一个额外的好处,就是能够更好地描述每个枚举的名称)。我不知道是不是因为。网络更新与否,但无论如何,我认为这是最好的方式。你需要添加一个参考:

使用系统组件模型;

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

然后,当你想访问数据时,使用以下两行:

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

这可能永远不会出现在所有其他响应中,但这是我想出的代码,如果它存在的话,这有使用 DescriptionAttribute的好处,除此之外使用枚举值本身的名称。

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

我得到的成员具有 MemberTypeField的字面值。这将创建一个仅为枚举值的成员序列。这是健壮的,因为枚举不能有其他字段。

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




}

这对我很有效:

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