数据将枚举属性绑定到网格并显示描述

这是一个类似于如何将自定义枚举描述绑定到DataGrid的问题 ,但在我的情况下,我有多个属性。

public enum ExpectationResult { [Description("-")] NoExpectation, [Description("Passed")] Pass, [Description("FAILED")] Fail } public class TestResult { public string TestDescription { get; set; } public ExpectationResult RequiredExpectationResult { get; set; } public ExpectationResult NonRequiredExpectationResult { get; set; } } 

我将BindingList 绑定到WinForms DataGridView(实际上是DevExpress.XtraGrid.GridControl,但通用解决方案将更广泛适用)。 我想要出现描述而不是枚举名称。 我怎么能做到这一点? (class / enum / attributes没有约束;我可以随意更改它们。)

TypeConverter通常会完成这项工作; 这里有一些适用于DataGridView代码 – 只需添加代码来阅读描述(通过reflection等 – 我现在只使用字符串前缀来显示自定义代码的工作原理)。

请注意,您可能也想要覆盖ConvertFrom 。 可以在类型属性级别指定转换器(如果您只希望它应用于某些属性),并且如果枚举不在您的控制之下,也可以在运行时应用。

 using System.ComponentModel; using System.Windows.Forms; [TypeConverter(typeof(ExpectationResultConverter))] public enum ExpectationResult { [Description("-")] NoExpectation, [Description("Passed")] Pass, [Description("FAILED")] Fail } class ExpectationResultConverter : EnumConverter { public ExpectationResultConverter() : base( typeof(ExpectationResult)) { } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { if (destinationType == typeof(string)) { return "abc " + value.ToString(); // your code here } return base.ConvertTo(context, culture, value, destinationType); } } public class TestResult { public string TestDescription { get; set; } public ExpectationResult RequiredExpectationResult { get; set; } public ExpectationResult NonRequiredExpectationResult { get; set; } static void Main() { BindingList list = new BindingList(); DataGridView grid = new DataGridView(); grid.DataSource = list; Form form = new Form(); grid.Dock = DockStyle.Fill; form.Controls.Add(grid); Application.Run(form); } } 

我不确定这有多大帮助,但我在Enum上使用了一个扩展方法,如下所示:

  ///  /// Returns the value of the description attribute attached to an enum value. ///  ///  /// The text from the System.ComponentModel.DescriptionAttribute associated with the enumeration value. ///  /// To use this, create an enum and mark its members with a [Description("My Descr")] attribute. /// Then when you call this extension method, you will receive "My Descr". ///  ///  /// enum MyEnum { /// [Description("Some Descriptive Text")] /// EnumVal1, /// /// [Description("Some More Descriptive Text")] /// EnumVal2 /// } /// /// static void Main(string[] args) { /// Console.PrintLine( MyEnum.EnumVal1.GetDescription() ); /// } ///  /// /// This will result in the output "Some Descriptive Text". ///  public static string GetDescription(this Enum en) { var type = en.GetType(); var memInfo = type.GetMember(en.ToString()); if (memInfo != null && memInfo.Length > 0) { var attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false); if (attrs != null && attrs.Length > 0) return ((DescriptionAttribute)attrs[0]).Description; } return en.ToString(); } 

您可以在对象上使用自定义属性getter来返回名称:

 public class TestResult { public string TestDescription { get; set; } public ExpectationResult RequiredExpectationResult { get; set; } public ExpectationResult NonRequiredExpectationResult { get; set; } /* *** added these new property getters *** */ public string RequiredExpectationResultDescr { get { return this.RequiredExpectationResult.GetDescription(); } } public string NonRequiredExpectationResultDescr { get { return this.NonRequiredExpectationResult.GetDescription(); } } } 

然后将网格绑定到“RequiredExpectationResultDescr”和“NonRequiredExpectationResultDescr”属性。

这可能有点过于复杂,但它是我提出的第一件事:)

基于另外两个答案,我将一个类放在一起,可以使用每个枚举值的Description属性在任意枚举和字符串之间进行一般转换。

这使用System.ComponentModel作为DescriptionAttribute的定义,并且仅支持T和String之间的转换。

 public class EnumDescriptionConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return (sourceType == typeof(T) || sourceType == typeof(string)); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return (destinationType == typeof(T) || destinationType == typeof(string)); } public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { Type typeFrom = context.Instance.GetType(); if (typeFrom == typeof(string)) { return (object)GetValue((string)context.Instance); } else if (typeFrom is T) { return (object)GetDescription((T)context.Instance); } else { throw new ArgumentException("Type converting from not supported: " + typeFrom.FullName); } } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { Type typeFrom = value.GetType(); if (typeFrom == typeof(string) && destinationType == typeof(T)) { return (object)GetValue((string)value); } else if (typeFrom == typeof(T) && destinationType == typeof(string)) { return (object)GetDescription((T)value); } else { throw new ArgumentException("Type converting from not supported: " + typeFrom.FullName); } } public string GetDescription(T en) { var type = en.GetType(); var memInfo = type.GetMember(en.ToString()); if (memInfo != null && memInfo.Length > 0) { var attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false); if (attrs != null && attrs.Length > 0) return ((DescriptionAttribute)attrs[0]).Description; } return en.ToString(); } public T GetValue(string description) { foreach (T val in Enum.GetValues(typeof(T))) { string currDescription = GetDescription(val); if (currDescription == description) { return val; } } throw new ArgumentOutOfRangeException("description", "Argument description must match a Description attribute on an enum value of " + typeof(T).FullName); } }