将枚举值绑定到 ComboBox
一种简洁通用的解决方案,用于将枚举(带或不带 DescriptionAttribute)绑定到 ComboBox 或其他控件
引言
这里提供的解决方案提供了一种简单而简洁的方法,可以将 Enum
绑定到 ComboBox
,或者(只需进行少量调整)绑定到任何其他可绑定的控件。 如果您使用 DescriptionAttribute 装饰了您的 Enum
成员,则可以使用该描述作为控件绑定的 DisplayMember
,否则可以使用 Enum
成员的名称代替。
背景
这个技巧的想法源于我对 CodeProject Q&A 中最近一个问题的回答,在评论中有人建议我将其写成一个技巧。 Q&A 提问者在 Code Review (StackExchange) 上的一个问题 中遇到了一个提出的解决方案的实现问题(尤其是 StackExchange 成员 Jesse C. Slicer)。 我只声称对使其成为一个通用解决方案(以及进行一些其他小的改进)并将其打包成一个简洁的示例负责。
Using the Code
该示例使用了这两个 Enum
定义 - 一个带有 Description 属性,一个没有。
public enum AnimalOption
{
[Description("flying animal")]
Bird,
[Description("best friend")]
Dog,
[Description("cuddly carnivore")]
Cat
}
public enum ShapeOption
{
Circle,
Rectangle,
Line
}
它们在 Form
的构造函数中绑定到 ComboBox
。 如您所见,它是通过一个泛型扩展方法到 ComboBox
完成的,该方法将 Enum
类型作为泛型类型参数,并带有一个 DisplayMode
参数,该参数指示它是否应该查找 Description 属性以用于 DisplayMember
,或者使用 Enum
成员的名称代替(ValueToString
)。
public Form1()
{
InitializeComponent();
AnimalComboBox.BindEnum<AnimalOption>(DisplayMode.DescriptionAttribute);
ShapeComboBox.BindEnum<ShapeOption>(DisplayMode.ValueToString);
}
扩展方法的实现及其“助手”如下
public class EnumBindingItem<TEnum>
{
public string Description { get; private set; }
public TEnum Value { get; set; } // setter needs to be public for the binding to work
public EnumBindingItem(string description, TEnum value)
{
Description = description;
Value = value;
}
}
public enum DisplayMode
{
DescriptionAttribute,
ValueToString
}
public static class EnumBindingExtension
{
public static void BindEnum<TEnum>(this ComboBox cbo, DisplayMode mode)
{
cbo.DataSource = Enum.GetValues(typeof(TEnum))
.Cast<TEnum>()
.Select(value => CreateEnumBindingItem(value, mode))
.OrderBy(item => item.Value)
.ToList();
cbo.DisplayMember = "Description";
cbo.ValueMember = "Value";
}
private static EnumBindingItem<TEnum> CreateEnumBindingItem<TEnum>(TEnum value, DisplayMode mode)
{
string description;
if (mode == DisplayMode.DescriptionAttribute)
{
FieldInfo enumMember = typeof(TEnum).GetField(value.ToString());
DescriptionAttribute attribute = (DescriptionAttribute)
Attribute.GetCustomAttribute(enumMember, typeof(DescriptionAttribute));
description = attribute.Description;
}
else
{
description = value.ToString();
}
return new EnumBindingItem<TEnum>(description, value);
}
}
在 ComboBox
的 SelectedValueChanged
事件处理程序中,您可以轻松地获取所选的 Enum
值,如下所示
private void AnimalComboBoxSelectedValueChanged(object sender, EventArgs e)
{
AnimalOption selectedAnimal = ((EnumBindingItem<AnimalOption>)AnimalComboBox.SelectedItem).Value;
AnimalSelectionLabel.Text = selectedAnimal.ToString();
}
private void ShapeComboBoxSelectedValueChanged(object sender, EventArgs e)
{
ShapeOption selectedShape = ((EnumBindingItem<ShapeOption>)ShapeComboBox.SelectedItem).Value;
ShapeSelectionLabel.Text = selectedShape.ToString();
}
希望对您有所帮助! 欢迎提出评论!
历史
- v1.1 - 2015年3月16日
- 合并了 Klaus Luedenscheidt 的建议和 Sergey Alexandrovich Kryukov 的一个建议。 没有功能性更改。
- v1.0 - 2015年3月15日