我想要在弹出菜单打开时显示枚举项目的描述。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
contact c = new contact();
c.Friend = new person { Name = "ali", Phone = phone.homeNumber };
propertyGrid1.SelectedObject = c;
}
}
class contact
{
public contact()
{
}
[Browsable(true),ReadOnly(false)]
public person Friend { get; set; }
}
public enum phone
{
[Description("Home Number")]
homeNumber,
[Description("Mobile Number")]
mobileNumber,
}
[TypeConverter(typeof(ExpandableObjectConverter))]
class person
{
public string Name { get; set; }
public phone Phone { get; set; }
}
我希望当手机弹出菜单打开时显示" Home Number"和"手机号码"
答案 0 :(得分:2)
试试这个创建一个类
public static class Util
{
public static T StringToEnum<T>(string name)
{
return (T)Enum.Parse(typeof(T), name);
}
public static string ToDescriptionString(this Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes != null &&
attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
}
你的方法
string phone = Util.ToDescriptionString(phone.homeNumber)
更新:
public Form1()
{
InitializeComponent();
contact c = new contact();
c.Friend = new person { Name = "ali", Phone = Util.ToDescriptionString(phone.homeNumber) };
propertyGrid1.SelectedObject = c;
}
答案 1 :(得分:1)
属性网格本身不支持,您需要添加自定义UITypeEditor。理想情况下,您还需要一个自定义TypeConverter来支持Description属性作为显示,并且还允许使用Description进行键盘输入。以下是如何声明枚举类型:
[Editor(typeof(MyEnumEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(MyEnumConverter<phone>))]
public enum phone
{
[Description("Home Number")]
homeNumber,
[Description("Mobile Number")]
mobileNumber,
}
以下是代码:
public class MyEnumEditor : UITypeEditor
{
private IWindowsFormsEditorService _editorService;
private bool _cancel;
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
_editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
ListBox listBox = new ListBox();
listBox.DisplayMember = "Name"; // EnumItem 'Name' property
listBox.IntegralHeight = true;
listBox.SelectionMode = SelectionMode.One;
listBox.MouseClick += OnListBoxMouseClick;
listBox.KeyDown += OnListBoxKeyDown;
listBox.PreviewKeyDown += OnListBoxPreviewKeyDown;
Type enumType = value.GetType();
if (!enumType.IsEnum)
throw new InvalidOperationException();
foreach (FieldInfo fi in enumType.GetFields(BindingFlags.Public | BindingFlags.Static))
{
EnumItem item = new EnumItem();
item.Value = fi.GetValue(null);
object[] atts = fi.GetCustomAttributes(typeof(DescriptionAttribute), true);
if (atts != null && atts.Length > 0)
{
item.Name = ((DescriptionAttribute)atts[0]).Description;
}
else
{
item.Name = fi.Name;
}
int index = listBox.Items.Add(item);
if (fi.Name == value.ToString())
{
listBox.SetSelected(index, true);
}
}
_cancel = false;
_editorService.DropDownControl(listBox);
if (_cancel || listBox.SelectedIndices.Count == 0)
return value;
return ((EnumItem)listBox.SelectedItem).Value;
}
private class EnumItem
{
public object Value { get; set; }
public string Name { get; set; }
}
private void OnListBoxPreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
_cancel = true;
_editorService.CloseDropDown();
}
}
private void OnListBoxMouseClick(object sender, MouseEventArgs e)
{
int index = ((ListBox)sender).IndexFromPoint(e.Location);
if (index >= 0)
{
_editorService.CloseDropDown();
}
}
private void OnListBoxKeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
_editorService.CloseDropDown();
}
}
}
public class MyEnumConverter<TEnum> : TypeConverter where TEnum : struct
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
string svalue = string.Format(culture, "{0}", value);
TEnum e;
if (Enum.TryParse(svalue, out e))
return e;
foreach (FieldInfo fi in typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.Static))
{
object[] atts = fi.GetCustomAttributes(typeof(DescriptionAttribute), true);
if (atts != null && atts.Length > 0)
{
if (string.Compare(((DescriptionAttribute)atts[0]).Description, svalue, StringComparison.OrdinalIgnoreCase) == 0)
return fi.GetValue(null);
}
}
return base.ConvertFrom(context, culture, value);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
string svalue = string.Format(culture, "{0}", value);
foreach (FieldInfo fi in typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.Static))
{
object[] atts = fi.GetCustomAttributes(typeof(DescriptionAttribute), true);
if (atts != null && atts.Length > 0)
{
if (string.Compare(fi.Name, svalue, StringComparison.OrdinalIgnoreCase) == 0)
return ((DescriptionAttribute)atts[0]).Description;
}
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
注意:此代码不支持带有Flags属性的枚举,可以修改它以执行此操作。