場景:
DatagridView中有一個ComboBox列,希望該列綁定到某個對象的一個枚舉類型的成員,同時,Combox下拉列表顯示的是枚舉的Description。
如定義類RowItem和枚舉 TypeEnum,我們希望在UI上顯示的是”A相“和”B相“而不是”A“和”B“。
public class RowItem
{
TypeEnum t = TypeEnum.A;
public TypeEnum T
{
get => t;
set => t = value;
}
}
public enum TypeEnum
{
[Description("A相")]
A,
[Description("B相")]
B
}
實現方法:
為了達到該目的,我們可以通過設置EnumConverter來實現:
[TypeConverter(typeof(TypeEnumConverter))]
public enum TypeEnum
{
[Description("A相")]
A,
[Description("B相")]
B
}
public class TypeEnumConverter : EnumConverter
{
public TypeEnumConverter() : base(typeof(TypeEnum))
{
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string)
{
return (value as string).GetEnumFormDescription<TypeEnum>();
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if(value is TypeEnum)
{
return ((TypeEnum)value).GetEnumDescription();
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
/// <summary>
/// 輔助拓展方法用於Descripition和枚舉值之間的轉換
/// </summary>
public static class EnumExtension
{
public static T GetEnumFormDescription<T>(this string description) where T : Enum
{
var values = typeof(T).GetEnumValues();
var targets = values.OfType<T>().Where(v => v.GetEnumDescription() == description);
foreach ( T item in targets)
{
return item;
}
throw new ArgumentException("Not found.", nameof(description));
}
public static string GetEnumDescription(this Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];
if (attributes != null && attributes.Any())
{
return attributes.First().Description;
}
return value.ToString();
}
}
UI的代碼如下
public partial class Form1 : Form { public Form1() { InitializeComponent(); InitDgv(); } BindingList<RowItem> blist = new BindingList<RowItem>(); private void InitDgv() { var column=new DataGridViewComboBoxColumn(); column.HeaderText = "類型"; column.DataPropertyName = nameof(RowItem.T); column.DataSource = Enum.GetValues(typeof(TypeEnum));//設置Combbox下拉列表, //此處不應該調用column.Items.Add() dataGridView1.Columns.Add(column); blist.Add(new RowItem()); dataGridView1.DataSource = blist; } }
運行截圖如下