Dot-Net

.NET 將組合框數據綁定到具有描述屬性的字元串列舉

  • August 8, 2011

我有一個這樣的列舉:

public enum Cities
{
   [Description("New York City")]
   NewYork,
   [Description("Los Angeles")]
   LosAngeles,
   Washington,
   [Description("San Antonio")]
   SanAntonio,
   Chicago
}

我想把它綁定到一個組合框,我試過這個:

comboBox.DataSource = Enum.GetNames(typeof(Cities));

但這會顯示組合框中的值而不是字元串描述。所以我切換到這個:

public static string GetEnumDescription(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();
   }
}

public static IList ToList(this Type type)
{
   ArrayList list = new ArrayList();
   Array enumValues = Enum.GetValues(type);

   foreach (Enum value in enumValues)
   {
       list.Add(new KeyValuePair<Enum, string>(value, GetEnumDescription(value)));
   }

   return list;
}

現在 list.Add() 呼叫會產生值,它的字元串描述顯示在組合框中,所以我替換了

list.Add(new KeyValuePair<Enum, string>(value, GetEnumDescription(value)));

list.Add(GetEnumDescription(value));

現在我得到的只是組合框中顯示的描述性字元串,這是我最終想要的。現在我的數據綁定被破壞了,因為它無法在列舉中找到字元串描述。我認為這可能與 combobox.DisplayMember 和 combobox.ValueMember 有關,但我還沒有解決這個問題。誰能告訴我如何顯示描述性字元串但讓我的數據綁定使用該值進行儲存等?謝謝!!!

讓我們回到我幾天前回答的問題,並對其進行修改以適應您的新要求。所以我會在這個問題中保留這個colorEnum例子來代替你的Cities列舉。

您已經完成了大部分工作 - 您已經獲得了從列舉到描述字元串的程式碼;現在你只需要回到另一條路。

public static class EnumHelper
{
   // your enum->string method (I just decluttered it a bit :))
   public static string GetEnumDescription(Enum value)
   {
       var fi = value.GetType().GetField(value.ToString());
       var attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

       if (attributes.Length > 0)
           return ((DescriptionAttribute)attributes[0]).Description;
       else
           return value.ToString();        
   }

   // the method to go from string->enum
   public static T GetEnumFromDescription<T>(string stringValue)
       where T : struct
   {
       foreach (object e in Enum.GetValues(typeof(T)))           
           if (GetEnumDescription((Enum)e).Equals(stringValue))
               return (T)e;
       throw new ArgumentException("No matching enum value found.");
   }

   // and a method to get a list of string values - no KeyValuePair needed
   public static IEnumerable<string> GetEnumDescriptions(Type enumType)
   {
       var strings = new Collection<string>();
       foreach (Enum e in Enum.GetValues(enumType))   
           strings.Add(GetEnumDescription(e));
       return strings;
   }
}

現在,拿你幾天前的東西…

public class Person 
{
   [...]
   public colorEnum FavoriteColor { get; set; }
   public string FavoriteColorString
   {
       get { return FavoriteColor.ToString(); }
       set { FavoriteColor = (colorEnum)Enum.Parse(typeof(colorEnum), value);  }
   }
}

並將其更改為:

public class Person 
{
   [...]
   public colorEnum FavoriteColor { get; set; }
   public string FavoriteColorString
   {
       get { return EnumHelper.GetEnumDescription(FavoriteColor); }
       set { FavoriteColor = EnumHelper.GetEnumFromDescription<colorEnum>(value); }
   }
}

和以前一樣,您將組合框SelectedItem值綁定到FavoriteColorString. 如果您仍然像在另一個問題中那樣使用 BindingSource,則不需要設置 DisplayMember 或 ValueMember 屬性,我假設您是。

並將組合框填充程式碼更改為:

comboBoxFavoriteColor.DataSource = Enum.GetNames(typeof(colorEnum));

comboBoxFavoriteColor.DataSource = EnumHelper.GetEnumDescriptions(typeof(colorEnum));

現在你擁有了世界上最好的。使用者看到描述,您的程式碼包含列舉名稱,數據儲存包含列舉值。

引用自:https://stackoverflow.com/questions/6920767