2014-04-19 44 views
0

我想在彈出菜單打開時顯示枚舉項的說明。如何顯示屬性網格中彈出菜單中枚舉項的說明C#

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; } 
} 

我想在手機彈出菜單中打開顯示 「住宅電話」 和 「手機號碼」

回答

1

屬性網格本身不支持,您需要添加自定義UITypeEditor。理想情況下,您還需要一個自定義TypeConverter來支持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); 
    } 
} 

注:此代碼不支持與旗枚舉屬性,它可以被修改,以做所以。

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) 

UPDATE :

public Form1() 
    { 
     InitializeComponent(); 
     contact c = new contact(); 
     c.Friend = new person { Name = "ali", Phone = Util.ToDescriptionString(phone.homeNumber) }; 
     propertyGrid1.SelectedObject = c; 
    } 
+0

我收到此錯誤在 string phone = Util.ToDescriptionString(phone.homeNumber) 字段初始值設定項無法引用非靜態字段 – sharafi

+0

您能否顯示您已完成的操作。否則你可以刪除靜態類並創建普通類並使用該類的引用訪問該方法 – Nilesh

+0

我必須使用 string phone = Util.ToDescriptionString(phone.homeNumber)? – sharafi