.NET使用Description属性将组合框数据绑定到字符串枚举

bmt*_*033 7 .net data-binding combobox enumeration winforms

我有这样的枚举:

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

我想将它绑定到一个组合框,我试过这个:

comboBox.DataSource = Enum.GetNames(typeof(Cities));
Run Code Online (Sandbox Code Playgroud)

但是,它显示组合框中的值而不是字符串描述.所以我改用这个:

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;
}
Run Code Online (Sandbox Code Playgroud)

现在list.Add()调用会产生值,并且它的字符串描述显示在组合框中,所以我替换了

list.Add(new KeyValuePair<Enum, string>(value, GetEnumDescription(value)));
Run Code Online (Sandbox Code Playgroud)

list.Add(GetEnumDescription(value));
Run Code Online (Sandbox Code Playgroud)

现在我只得到组合框中显示的描述性字符串,这是我最终想要的.现在我的数据绑定被破坏了,因为它无法在枚举中找到字符串描述.我认为这可能与combobox.DisplayMember和combobox.ValueMember有关,但我还没能解决问题.任何人都可以告诉我如何显示描述性字符串,但我的数据绑定使用值存储等?谢谢!!!

Igb*_*man 9

让我们回到几天前我回答的问题并根据您的新要求进行修改.所以我会在这个问题中保留colorEnum代表你的Cities枚举的例子.

你大部分时间都在那里 - 你有从enum到描述字符串的代码; 现在你只需要回到另一个方向.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,拿几天前的东西......

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

并将其改为:

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

和以前一样,你将组合框的SelectedItem值绑定到FavoriteColorString.如果您仍在使用BindingSource,则无需设置DisplayMember或ValueMember属性,就像您在其他问题中一样,我假设您是这样.

并从以下位置更改组合框填充代码:

comboBoxFavoriteColor.DataSource = Enum.GetNames(typeof(colorEnum));
Run Code Online (Sandbox Code Playgroud)

comboBoxFavoriteColor.DataSource = EnumHelper.GetEnumDescriptions(typeof(colorEnum));
Run Code Online (Sandbox Code Playgroud)

现在你拥有最好的世界.用户看到描述,您的代码包含枚举名称,数据存储包含枚举值.

  • @ user68:不客气。顺便说一下,我在`GetEnumDescription()` 中删除`attributes != null` 检查的原因是`GetCustomAttributes()` 在没有找到任何属性时只返回一个空数组。 (2认同)