WinForm下ComboBox SelectedValue转换为Enum类型报错如何解决?
问题根因
你绑定的数据源项的Value属性本身就是MyEnum类型,理论上设置ValueMember = "Value"后SelectedValue应直接返回枚举值。你遇到报错是因为此时SelectedValue实际返回了整个匿名类实例,调用ToString()后得到匿名类的默认输出格式{ Text = xxx, Value = xxx },这个字符串不是枚举的有效名称,传入Enum.Parse自然抛出找不到请求值的异常。
导致SelectedValue未返回预期值的常见原因有两个:
- 绑定顺序问题:设置
DataSource的时机早于DisplayMember、ValueMember的设置,绑定上下文未正确解析字段映射 - 匿名类的访问限制:部分.NET Framework版本下,匿名类的内部属性可能导致
ValueMember绑定失效
解决方案
下面按稳妥性从高到低给出方案:
方案1:直接强转SelectedValue(推荐)
既然Value本身就是MyEnum类型,不需要做字符串解析,直接强转即可,建议增加空判断避免异常:
if (MyCombo.SelectedValue is MyEnum getEnum) { // 直接使用getEnum即可 }
如果还是出现类型转换失败,调整绑定顺序,先设置显示/值成员再绑定数据源:
MyCombo.DisplayMember = "Text"; MyCombo.ValueMember = "Value"; MyCombo.DataSource = EnumItems; // 最后赋值DataSource
方案2:通过SelectedItem取值(兼容绑定异常场景)
如果调整绑定顺序后SelectedValue还是返回整个数据项,直接从SelectedItem中取Value属性即可:
// 用动态类型读取匿名类的Value属性 dynamic selectedItem = MyCombo.SelectedItem; MyEnum getEnum = selectedItem.Value;
方案3:使用强类型绑定类(彻底避免匿名类问题)
为了彻底规避匿名类带来的绑定不可靠问题,建议定义通用的枚举绑定强类型类:
public class EnumBindItem<T> where T : Enum { public string Text { get; set; } public T Value { get; set; } }
绑定代码修改为:
var EnumItems = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Select(item => new EnumBindItem<MyEnum> { Text = item.GetEnumName(), Value = item }).ToList(); MyCombo.DisplayMember = "Text"; MyCombo.ValueMember = "Value"; MyCombo.DataSource = EnumItems;
取值代码:
var selectedItem = MyCombo.SelectedItem as EnumBindItem<MyEnum>; if (selectedItem != null) { MyEnum getEnum = selectedItem.Value; }
内容的提问来源于stack exchange,提问作者I'mBehnam
相关产品推荐
相关产品推荐

