使用本地化枚举作为数据源

发布于 2024-12-17 01:38:49 字数 312 浏览 3 评论 0原文

我的应用程序中有很多枚举。它们中的大多数用于像这样的组合:

Enum.GetValues(typeof(TipoControlador))

现在我想像这样本地化它们: 本地化枚举描述属性

如何组合它们?我的第一个想法是用扩展方法覆盖 ToString 方法,但这是不可能的 =(

I've lots of enums in my app. Most of them are used on combos like this:

Enum.GetValues(typeof(TipoControlador))

Now I'd like to localize them like this: Localizing enum descriptions attributes

How can I combine them? My first thought was to override the ToString method with an extension method, but that's not possible =(

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

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

发布评论

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

评论(3

入怼 2024-12-24 01:38:49

使用另一篇文章作为基础,您可以创建一个如下所示的扩展方法:

public static class LocalizedEnumExtensions
{
    private static ResourceManager _resources = new ResourceManager("MyClass.myResources",
        System.Reflection.Assembly.GetExecutingAssembly());

    public static IEnumerable<string> GetLocalizedNames(this IEnumerable enumValues)
    {
        foreach(var e in enumValues)
        {
            string localizedDescription = _resources.GetString(String.Format("{0}.{1}", e.GetType(), e));
            if(String.IsNullOrEmpty(localizedDescription))
            {
                yield return e.ToString();
            }
            else
            {
                yield return localizedDescription;
            }
        }
    }
}

您可以像这样使用它:

Enum.GetValues(typeof(TipoControlador)).GetLocalizedNames();

从技术上讲,此扩展方法将接受任何数组,并且您不能将其限制为仅适用于枚举,但是您如果您认为很重要,可以在扩展方法中添加额外的验证:

if(!e.GetType().IsEnum) throw new InvalidOperationException(String.Format("{0} is not a valid Enum!", e.GetType()));

Using the other article as a basis, you can create an extension method like this:

public static class LocalizedEnumExtensions
{
    private static ResourceManager _resources = new ResourceManager("MyClass.myResources",
        System.Reflection.Assembly.GetExecutingAssembly());

    public static IEnumerable<string> GetLocalizedNames(this IEnumerable enumValues)
    {
        foreach(var e in enumValues)
        {
            string localizedDescription = _resources.GetString(String.Format("{0}.{1}", e.GetType(), e));
            if(String.IsNullOrEmpty(localizedDescription))
            {
                yield return e.ToString();
            }
            else
            {
                yield return localizedDescription;
            }
        }
    }
}

You would use it like this:

Enum.GetValues(typeof(TipoControlador)).GetLocalizedNames();

Technically, this extension method will accept any array, and you can't restrict it to only work on an enum, but you could add extra validation inside the extension method if you feel it's important:

if(!e.GetType().IsEnum) throw new InvalidOperationException(String.Format("{0} is not a valid Enum!", e.GetType()));
回忆那么伤 2024-12-24 01:38:49

这里有两个问题,第一个问题是如何本地化枚举,这是通过 本地化枚举描述解决的属性

第二个是如何在使用枚举值的同时显示本地化名称。这可以通过创建一个简单的包装对象来解决,例如:

public sealed class NamedItem
{
    private readonly string name;
    private readonly object value;

    public NamedItem (string name, object value)
    {
        this.name = name;
        this.value = value;
    }

    public string Name { get { return name; } }
    public object Value { get { return value; } }

    public override string ToString ()
    {
        return name;
    }
}

这为任何下拉框提供了一个通用的可重用类,您可能希望在其中显示项目名称而不是项目本身提供的名称(例如枚举、整数等) )。

拥有此类后,您可以将下拉列表的 DisplayMember 设置为 Name,将 ValueMember 设置为 Value。这意味着 dropdown.SelectedValue 仍将返回您的枚举。

You have 2 problems here, the first is how to localize enums which is solved by Localizing enum descriptions attributes.

The second is how to display the localized name whilst using the enum's value. This can be solved by creating a simple wrapper object such as:

public sealed class NamedItem
{
    private readonly string name;
    private readonly object value;

    public NamedItem (string name, object value)
    {
        this.name = name;
        this.value = value;
    }

    public string Name { get { return name; } }
    public object Value { get { return value; } }

    public override string ToString ()
    {
        return name;
    }
}

This provides a generic re-usable class for any drop down box where you might want to show a different name for an item than the item itself provides (eg enums, ints, etc).

Once you have this class, you can set the drop down's DisplayMember to Name and ValueMember to Value. This will mean that dropdown.SelectedValue will still return your enum.

鹤舞 2024-12-24 01:38:49

我知道这个问题很老了,但这可能对某些人有帮助。
您可以只处理 ComboBox 控件的 Format 事件 (http://msdn.microsoft.com/en-us/library/system.windows.forms.listcontrol.format.aspx),然后在其中添加文本逻辑。

    private void ComboBoxFormat(object sender, ListControlConvertEventArgs e)
    {
        e.Value = GetDescription(e.Value);
    }

    public static string GetDescription(object item)
    {
        string desc = null;

        Type type = item.GetType();
        MemberInfo[] memInfo = type.GetMember(item.ToString());
        if (memInfo != null && memInfo.Length > 0)
        {
            object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (attrs != null && attrs.Length > 0)
            {
                desc = (attrs[0] as DescriptionAttribute).Description;
            }
        }

        if (desc == null) // Description not found
        {
            desc = item.ToString();
        }

        return desc;
    }

这样,ComboBox 控件仍然保存枚举值而不是字符串。

I know this question is old, but this may help some people.
You can just handle the Format event of the ComboBox control (http://msdn.microsoft.com/en-us/library/system.windows.forms.listcontrol.format.aspx), and add your text logic in it.

    private void ComboBoxFormat(object sender, ListControlConvertEventArgs e)
    {
        e.Value = GetDescription(e.Value);
    }

    public static string GetDescription(object item)
    {
        string desc = null;

        Type type = item.GetType();
        MemberInfo[] memInfo = type.GetMember(item.ToString());
        if (memInfo != null && memInfo.Length > 0)
        {
            object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (attrs != null && attrs.Length > 0)
            {
                desc = (attrs[0] as DescriptionAttribute).Description;
            }
        }

        if (desc == null) // Description not found
        {
            desc = item.ToString();
        }

        return desc;
    }

With this, the ComboBox control still holds enum values rather than strings.

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