将枚举值转换为DropDownList等的选项值

应用场景:在项目中,我们已习惯将较稳定的分类标准定义为枚举,来保证程序中取值的合法性,也使代码更清晰。某些情况下我们需要在DropDownList等选择控件上绑定某个枚举的所有枚举值,供用户自行选择,这时就需要将枚举值转换为DropDownList等的选项值。

 

最初遇到这种需求时,我随手写了个简单的方法如下。

  • 枚举定义
/// <summary>
/// 紧急程度
/// </summary>
public enum eOA_EmergencyLevel
{
    /// <summary>
    /// 平件
    /// </summary>
    平件 = 1,
    /// <summary>
    /// 急件
    /// </summary>
    急件 = 2
}
  • 将枚举转换成ArrayList
/// <summary>
/// 将枚举转换成ArrayList
/// </summary>
/// <returns></returns>
public static IList EnumToList(Type enumType)
{
    ArrayList list = new ArrayList();

    foreach (int i in Enum.GetValues(enumType))
    {
        ListItem listitem = new ListItem(Enum.GetName(enumType, i), i.ToString());
        list.Add(listitem);
    }

    return list;
}
  • 绑定
/// <summary>
/// 将枚举转换成下拉框
/// </summary>
public static void FillDropDownList(DropDownList ddl, Type enumType)
{
    ddl.Items.Clear();
    ddl.DataSource = EnumToList(enumType);
    ddl.DataValueField = "value";
    ddl.DataTextField = "text";
    ddl.DataBind();
}

 

后来,在同事讨论代码时,被大家批评为不该使用这种中文的枚举名称;同时我自己也觉得这种反射方式性能有问题。不过因为影响不大,一直懒得去理它。

最近看到了两篇博文(枚举的显示和绑定一个利用扩展方法的实例:AttachDataExtensions),是利用C# 3.0的扩展方法实现的,实现得很是优美,可惜我们的项目基于.NET 2.0,用不上。但受此启发,便花了点时间使用Attribute和缓存的技术重构了原来的代码。

  • EnumShowNameAttribute
/// <summary>
/// 枚举的显示名称
/// </summary>
[global::System.AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
public sealed class EnumShowNameAttribute : Attribute
{
    private string showName;

    /// <summary>
    /// 显示名称
    /// </summary>
    public string ShowName
    {
        get
        {
            return this.showName;
        }
    }

    /// <summary>
    /// 构造枚举的显示名称
    /// </summary>
    /// <param name="showName">显示名称</param>
    public EnumShowNameAttribute(string showName)
    {
        this.showName = showName;
    }
}
  • 枚举定义
/// <summary>
/// 紧急程度
/// </summary>
public enum eOA_EmergencyLevel
{
    /// <summary>
    /// 平件
    /// </summary>
    [EnumShowName("平件")]
    Common = 1,
    /// <summary>
    /// 急件
    /// </summary>
    [EnumShowName("急件")]
    Emergency = 2
}
  • 枚举工具类
/// <summary>
/// 枚举工具类
/// </summary>
public sealed class EnumUtil
{
    private static Dictionary<string, Dictionary<int, string>> _EnumList = new Dictionary<string, Dictionary<int, string>>(); //枚举缓存池

    /// <summary>
    /// 将枚举绑定到ListControl
    /// </summary>
    /// <param name="listControl">ListControl</param>
    /// <param name="enumType">枚举类型</param>
    public static void FillListControl(ListControl listControl, Type enumType)
    {
        listControl.Items.Clear();
        listControl.DataSource = EnumToDictionary(enumType);
        listControl.DataValueField = "key";
        listControl.DataTextField = "value";
        listControl.DataBind();
    }

    /// <summary>
    /// 将枚举转换成Dictionary&lt;int, string&gt;
    /// Dictionary中,key为枚举项对应的int值;value为:若定义了EnumShowName属性,则取它,否则取name
    /// </summary>
    /// <param name="enumType">枚举类型</param>
    /// <returns></returns>
    public static Dictionary<int, string> EnumToDictionary(Type enumType)
    {
        string keyName = enumType.FullName;

        if (!_EnumList.ContainsKey(keyName))
        {
            Dictionary<int, string> list = new Dictionary<int, string>();

            foreach (int i in Enum.GetValues(enumType))
            {
                string name = Enum.GetName(enumType, i);

                //取显示名称
                  string showName = string.Empty;
                object[] atts = enumType.GetField(name).GetCustomAttributes(typeof(EnumShowNameAttribute), false);
                if (atts.Length > 0) showName = ((EnumShowNameAttribute)atts[0]).ShowName;

                list.Add(i, string.IsNullOrEmpty(showName) ? name : showName);
            }

            object syncObj = new object();

            if (!_EnumList.ContainsKey(keyName))
            {
                lock (syncObj)
                {
                    if (!_EnumList.ContainsKey(keyName))
                    {
                        _EnumList.Add(keyName, list);
                    }
                }
            }
        }

        return _EnumList[keyName];
    }

    /// <summary>
    /// 获取枚举值对应的显示名称
    /// </summary>
    /// <param name="enumType">枚举类型</param>
    /// <param name="intValue">枚举项对应的int值</param>
    /// <returns></returns>
    public static string GetEnumShowName(Type enumType, int intValue)
    {
        return EnumToDictionary(enumType)[intValue];
    }
}
 
想更偷懒的话,还可以省掉自定义的EnumShowNameAttribute,直接用System.ComponentModel.DescriptionAttribute就行了。

 

[附]Enum基础知识:

posted on 2009-06-19 10:21  wen.jian  阅读(7118)  评论(2编辑  收藏  举报