.NET 将组合框数据绑定到具有描述属性的字符串枚举

发布于 2024-11-27 11:58:45 字数 1532 浏览 1 评论 0原文

我有一个像这样的枚举:

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有关,但我还无法解决这个问题。谁能告诉我到底如何显示描述性字符串,但让我的数据绑定使用该值进行存储等?谢谢你!!!

I have an enum like this:

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

I want to bind this to a combobox and I've tried this:

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

But that displays the values in the combobox rather than the String description. So I switched to this:

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

Now the list.Add() call results in the value and it's string description being displayed in the combobox so I replaced

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

with

list.Add(GetEnumDescription(value));

and now I'm getting just the descriptive string displayed in the combobox which is what I ultimately want. Now my data binding is broken because it can't find just the string description in the enumeration. I thought this might be related to combobox.DisplayMember and combobox.ValueMember but I haven't been able to resolve the problem yet. Can anyone tell me how the heck I display the descriptive string but have my data binding use the value for storing, etc.? Thank you!!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你的背包 2024-12-04 11:58:45

让我们回到你的问题,我回答了一些几天前并修改它以满足您的新要求。因此,我将保留 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));

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

Let's go back to your question I answered a few days ago and modify that to suit your new requirements. So I'll keep the colorEnum example in place of your Cities enum in this question.

You're most of the way there - you've got the code to go from the enum to the description string; now you just need to go back the other way.

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

Now, take what you had a few days ago...

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

and just change it to this:

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

As before, you'll bind the combobox SelectedItem value to FavoriteColorString. You don't need to set the DisplayMember or ValueMember properties if you're still using the BindingSource as you were in the other question, which I assume you are.

And change the combobox populating code from:

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

to

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

Now you have the best of all worlds. The user sees the description, your code contains the enum names, and the data store contains the enum values.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文