枚举与ComboBox绑定的优雅实现

在开发过程中,经常需要将枚举类型与用户界面中的ComboBox控件绑定,以便用户可以从下拉列表中选择一个枚举值。然而,手动将枚举值映射到ComboBox的条目,然后根据用户的选择将其转换回相应的枚举值,这样的代码往往既丑陋又难以维护。幸运的是,C#3.0引入的扩展方法为提供了一个简单而优雅的解决方案。

扩展方法允许为现有类型添加新的方法,而不需要修改其源代码。通过添加对包含扩展方法的类的引用,并在代码中添加相应的命名空间,就可以轻松地将这些方法集成到目标类型中。

代码解释

为了实现所需的功能,定义了三个方法:

  • 一个用于将任何枚举类型与ComboBox实例绑定的方法。绑定后,ComboBox实例应该作为底层枚举类型的GUI表示。换句话说,ComboBox的条目应该与枚举字段紧密相关。
  • 一个用于检索当前选定的ComboBox条目的方法。
  • 一个用于更改ComboBox选择的方法。

这个方法使用反射来枚举给定枚举类型的所有字段。对于每个字段,它检索Description属性,以便在ComboBox条目中提供更友好的文本。然后,该方法将Description文本及其关联的枚举值添加到ComboBox条目列表中。

以下是BindWithEnum方法的实现:

public static void BindWithEnum<T>(this ComboBox comboBox, T selectedValue) { Type enumType = typeof(T); if (!enumType.IsEnum) throw new Exception("Only Enum types are allowed."); List<KeyValuePair<string, T>> comboBoxItems = new List<KeyValuePair<string, T>>(); KeyValuePair<string, T>? selectedItem = null; foreach (T enumValue in Enum.GetValues(enumType)) { string name = Enum.GetName(enumType, enumValue); FieldInfo fi = enumType.GetField(name); string descriptiveName = fi.GetDescriptionAttributeOrName(); KeyValuePair<string, T> item = new KeyValuePair<string, T>(descriptiveName, enumValue); comboBoxItems.Add(item); if (enumValue.Equals(selectedValue)) selectedItem = item; } comboBox.DisplayMember = "Key"; comboBox.ValueMember = "Value"; comboBox.DataSource = comboBoxItems; if (selectedItem != null) comboBox.SelectedItem = selectedItem.Value; }

这个方法首先检查传入的类型是否为枚举类型。如果不是,抛出异常。然后,它创建一个列表来存储ComboBox条目,并遍历枚举值以构建ComboBox条目列表。对于每个枚举值,它检索其描述性名称,并将其添加到列表中。最后,它将列表设置为ComboBox的数据源,并根据需要设置初始选择。

这个方法用于检索当前选定的ComboBox条目对应的枚举值。

public static T GetSelectedValue<T>(this ComboBox comboBox) { KeyValuePair<string, T> selectedItem = (KeyValuePair<string, T>)comboBox.SelectedItem; return (T)Convert.ChangeType(selectedItem.Value, typeof(T)); }

这个方法首先获取当前选定的ComboBox条目,然后将其转换为相应的枚举值并返回。

这个方法用于将ComboBox的选择设置为提供的枚举值。

public static void SetSelectedValue<T>(this ComboBox comboBox, T selectedValue) { string name = Enum.GetName(typeof(T), selectedValue); FieldInfo fi = typeof(T).GetField(name); string descriptiveName = fi.GetDescriptionAttributeOrName(); KeyValuePair<string, T> selectedItem = new KeyValuePair<string, T>(descriptiveName, selectedValue); comboBox.SelectedItem = selectedItem; }

这个方法首先获取枚举值的描述性名称,然后创建一个新的ComboBox条目,并将其设置为ComboBox的选定条目。

使用代码

使用这些扩展方法非常简单。只需在项目中添加对ComboBoxExtensions.dll的引用,并在代码中添加相应的using指令:

using Proxoft.WinForms;

然后,就可以使用这些扩展方法了。以下是一个示例,展示了如何将枚举与ComboBox绑定,并设置和检索当前选择:

[DefaultValue(OptionsToSelectFrom.opt3)] public enum OptionsToSelectFrom { [Description("选项一")] opt1, [Description("选项二")] opt2, [Description("选项三")] opt3, [Description("选项四")] opt4 } comboBox1.BindWithEnum<OptionsToSelectFrom>(OptionsToSelectFrom.opt3); comboBox1.SetSelectedValue<OptionsToSelectFrom>(OptionsToSelectFrom.opt2); private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { label1.Text = comboBox1.GetSelectedValue<OptionsToSelectFrom>().ToString(); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485