如何拥有用户友好的名称枚举? [英] How to have userfriendly names for enumerations?

查看:117
本文介绍了如何拥有用户友好的名称枚举?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像

Enum Complexity
{
  NotSoComplex,
  LittleComplex,
  Complex,
  VeryComplex
}

和我想用它在下拉列表中,但不希望看到这样的名单骆驼的名字(看起来非常奇怪的用户)。相反,我想有正常的措辞,像 没那么复杂 有点复杂(等)

And I want to use it in a dropdown list, but don't want to see such Camel names in list (looks really odd for users). Instead I would like to have in normal wording, like Not so complex Little complex (etc)

另外,我的应用程序是多浪,我想是能够显示这些字符串的本地化,我用一个帮手,TranslationHelper(字符串strID),这给了我一个字符串ID的本地化版本。

Also, my application is multi-lang and I would like to be able to display those strings localized, and I use a helper, TranslationHelper(string strID) which gives me the localized version for a string id.

我有一个有效的解决方案,但不是很优雅: 我创建覆盖一个辅助类的枚举,有一个成员复杂性和toString(),如下图所示(code简体)

I have a working solution, but not very elegant: I create a helper class for the enum, with one member Complexity and ToString() overwritten, like below (code simplified)

public class ComplexityHelper
{
    public ComplexityHelper(Complexity c, string desc)
    { m_complex = c; m_desc=desc; }

    public Complexity Complexity { get { ... } set {...} }
    public override ToString() { return m_desc; }

    //Then a static field like this 

    private static List<Complexity> m_cxList = null;

    // and method that returns the status lists to bind to DataSource of lists
    public static List<ComplexityHelper> GetComplexities() 
    {
        if (m_cxList == null)
        {
           string[] list = TranslationHelper.GetTranslation("item_Complexities").Split(',');
           Array listVal = Enum.GetValues(typeof(Complexities));
           if (list.Length != listVal.Length)
               throw new Exception("Invalid Complexities translations (item_Complexities)");
           m_cxList = new List<Complexity>();
           for (int i = 0; i < list.Length; i++)
           {
             Complexity cx = (ComplexitylistVal.GetValue(i);
             ComplexityHelper ch = new ComplexityHelper(cx, list[i]);
             m_cxList.Add(ch);
           }
        }
        return m_cxList;
    }
}

虽然可行,我不喜欢它,因为我有code它相若的各种枚举,我需要在选项列表中使用。

While workable, I'm not happy with it, since I have to code it similarily for various enums I need to use in picklists.

有没有人有一个建议,一个更为简单,更通用的解决方案?

Does anyone have a suggestion for a simpler or more generic solution?

谢谢 波格丹

推荐答案

感谢大家的所有答案。 最后,我用从雷克斯M和adrianbanks相结合,并加入我自己的改进,简化了绑定组合框。

Thank you all for all answers. Finally I used a combination from Rex M and adrianbanks, and added my own improvements, to simplify the binding to ComboBox.

进行必要的改变,因为当工作在code,有时我意识到我需要能够从组合中排除一个枚举项目。 例如。

The changes were needed because, while working on the code, I realized sometimes I need to be able to exclude one enumeration item from the combo. E.g.

Enum Complexity
{
  // this will be used in filters, 
  // but not in module where I have to assign Complexity to a field
  AllComplexities,  
  NotSoComplex,
  LittleComplex,
  Complex,
  VeryComplex
}

所以有时候我想选择列表显示所有,但AllComplexities(以附加 - 编辑模块)等时间来证明一切(滤镜)

So sometimes I want the picklist to show all but AllComplexities (in add - edit modules) and other time to show all (in filters)

下面是我所做的:

  1. 在我创建了一个扩展方法,使用说明属性本地化查找键。如果说明属性丢失,我创建查找定位键EnumName_ EnumValue。最后,如​​果翻译缺失我根据首字母大写,以不同的话只是分裂枚举名如图adrianbanks。顺便说一句,TranslationHelper是围绕resourceMgr.GetString包装(...)
  1. I created a extension method, that uses Description Attribute as localization lookup key. If Description attribute is missing, I create the lookup localization key as EnumName_ EnumValue. Finally, if translation is missing I just split enum name based on camelcase to separate words as shown by adrianbanks. BTW, TranslationHelper is a wrapper around resourceMgr.GetString(...)

满code如下所示

public static string GetDescription(this System.Enum value)
{
    string enumID = string.Empty;
    string enumDesc = string.Empty;
    try 
    {         
        // try to lookup Description attribute
        FieldInfo field = value.GetType().GetField(value.ToString());
        object[] attribs = field.GetCustomAttributes(typeof(DescriptionAttribute), true);
        if (attribs.Length > 0)
        {
            enumID = ((DescriptionAttribute)attribs[0]).Description;
            enumDesc = TranslationHelper.GetTranslation(enumID);
        }
        if (string.IsNullOrEmpty(enumID) || TranslationHelper.IsTranslationMissing(enumDesc))
        {
            // try to lookup translation from EnumName_EnumValue
            string[] enumName = value.GetType().ToString().Split('.');
            enumID = string.Format("{0}_{1}", enumName[enumName.Length - 1], value.ToString());
            enumDesc = TranslationHelper.GetTranslation(enumID);
            if (TranslationHelper.IsTranslationMissing(enumDesc))
                enumDesc = string.Empty;
        }

        // try to format CamelCase to proper names
        if (string.IsNullOrEmpty(enumDesc))
        {
            Regex capitalLetterMatch = new Regex("\\B[A-Z]", RegexOptions.Compiled);
            enumDesc = capitalLetterMatch.Replace(value.ToString(), " $&");
        }
    }
    catch (Exception)
    {
        // if any error, fallback to string value
        enumDesc = value.ToString();
    }

    return enumDesc;
}

我创建了一个基于枚举,它允许枚举轻松地绑定到数据源的通用助手类

I created a generic helper class based on Enum, which allow to bind the enum easily to DataSource

public class LocalizableEnum
{
    /// <summary>
    /// Column names exposed by LocalizableEnum
    /// </summary>
    public class ColumnNames
    {
        public const string ID = "EnumValue";
        public const string EntityValue = "EnumDescription";
    }
}

public class LocalizableEnum<T>
{

    private T m_ItemVal;
    private string m_ItemDesc;

    public LocalizableEnum(T id)
    {
        System.Enum idEnum = id as System.Enum;
        if (idEnum == null)
            throw new ArgumentException(string.Format("Type {0} is not enum", id.ToString()));
        else
        {
            m_ItemVal = id;
            m_ItemDesc = idEnum.GetDescription();
        }
    }

    public override string ToString()
    {
        return m_ItemDesc;
    }

    public T EnumValue
    {
        get { return m_ID; }
    }

    public string EnumDescription
    {
        get { return ToString(); }
    }

}

然后,我创建了一个返回列表>,如下图

Then I created a generic static method that returns a List>, as below

public static List<LocalizableEnum<T>> GetEnumList<T>(object excludeMember)
{
    List<LocalizableEnum<T>> list =null;
    Array listVal = System.Enum.GetValues(typeof(T));
    if (listVal.Length>0)
    {
        string excludedValStr = string.Empty;
        if (excludeMember != null)
            excludedValStr = ((T)excludeMember).ToString();

        list = new List<LocalizableEnum<T>>();
        for (int i = 0; i < listVal.Length; i++)
        {
            T currentVal = (T)listVal.GetValue(i);
            if (excludedValStr != currentVal.ToString())
            {
                System.Enum enumVal = currentVal as System.Enum;
                LocalizableEnum<T> enumMember = new LocalizableEnum<T>(currentVal);
                list.Add(enumMember);
            }
        }
    }
    return list;
}

和一个包装返回列表的所有成员

and a wrapper to return list with all members

public static List<LocalizableEnum<T>> GetEnumList<T>()
{
        return GetEnumList<T>(null);
}

现在,让我们把所有东西放在一起,并结合实际的组合:

Now let's put all things together and bind to actual combo:

// in module where we want to show items with all complexities
// or just filter on one complexity

comboComplexity.DisplayMember = LocalizableEnum.ColumnNames.EnumValue;
comboComplexity.ValueMember = LocalizableEnum.ColumnNames.EnumDescription;
comboComplexity.DataSource = EnumHelper.GetEnumList<Complexity>();
comboComplexity.SelectedValue = Complexity.AllComplexities;

// ....
// and here in edit module where we don't want to see "All Complexities"
comboComplexity.DisplayMember = LocalizableEnum.ColumnNames.EnumValue;
comboComplexity.ValueMember = LocalizableEnum.ColumnNames.EnumDescription;
comboComplexity.DataSource = EnumHelper.GetEnumList<Complexity>(Complexity.AllComplexities);
comboComplexity.SelectedValue = Complexity.VeryComplex; // set default value

要选择阅读的价值和使用它,我用code如下

To read selected the value and use it, I use code as below

Complexity selComplexity = (Complexity)comboComplexity.SelectedValue;

这篇关于如何拥有用户友好的名称枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆