【问题标题】:Using localized enum as DataSource使用本地化枚举作为数据源
【发布时间】:2011-11-18 21:28:50
【问题描述】:

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

Enum.GetValues(typeof(TipoControlador))

现在我想像这样对它们进行本地化:Localizing enum descriptions attributes

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

【问题讨论】:

  • 迭戈,是什么阻止了你应用这种方法:stackoverflow.com/questions/569298/…??
  • 我怎样才能将它们结合起来? 你是什么意思?制作标记的枚举值的字符串表示形式?
  • 如何更改someControl.DataSource = Enum.GetValues(typeof(TipoControlador)); 行以使用该方法?
  • @GertArnold 我想要的是总是调用 EnumDescription 方法,因为某些代码想要将我的枚举转换为字符串。

标签: c# .net winforms localization enums


【解决方案1】:

以另一篇文章为基础,可以这样创建扩展方法:

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()));

【讨论】:

  • 如果我这样做,那么我将无法将 combo.Value 转换为枚举,因为它将有一个字符串。
【解决方案2】:

这里有2个问题,第一个是如何本地化枚举,Localizing enum descriptions attributes解决了。

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

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 设置为NameValueMemberValue。这意味着dropdown.SelectedValue 仍将返回您的枚举。

【讨论】:

  • 我不喜欢这里是对象而不是特定类型。
  • 这并没有太大的区别,因为 dropdown.SelectedValue 返回一个对象,但如果您想更具体,可以很容易地将其更改为通用类型。
【解决方案3】:

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

    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 控件仍然保存枚举值而不是字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多