如何在属性网格C#的弹出菜单中显示枚举项的描述

时间:2014-04-19 06:43:03

标签: c# enums converter propertygrid

我想要在弹出菜单打开时显示枚举项目的描述。

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"和"手机号码"

2 个答案:

答案 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属性的枚举,可以修改它以执行此操作。