首页  ·  知识 ·  云计算
反射+特性列出所有的枚举变量及其描述信息,绑定到DropDownList上。
xbf321  http://www.cnblogs.com/xbf321/  综合  编辑:dezai  图片来源:网络
1。问题 在设计实体类的时候,通常我们会把某些字段设置为枚举值,例如性别: public enum Sex:int{&nbs

1。问题

    在设计实体类的时候,通常我们会把某些字段设置为枚举值,例如性别:

public enum Sex:int
{
    Male = 'M',Female = 'W',NotRestrict = 'A'
}   
    这样好处不用说,通常是为了直观的考虑,还有限制输入的好处;如果强制用int转换,还以用System.Enum.IsDefined() 来判断枚举是否被定义,但是麻烦的是在界面UI上绑定的时候,我们通常要这样写:

   
       
       
        不限
   
   
    然后如果要取得枚举的值,则:

    Sex sex = (Sex)ddlSex.SelectedValue.ToCharArray()[0];
    取值的时候其实没有多大问题,问题在UI上面

首先要知道所有枚举的值:例如'W','M','A'等
需要知道枚举值的名称,通常使用中文,例如'男','女'等,界面设计人员无法确定使用什么中文描述。
枚举的项目改变的时候,所有的绑定都需要改变。
2。解决了吗?

    解决描述的问题很简单,使用XML文档就可以了。
    只要在项目输出的时候输出XML文档,并且文档的名字跟DLL的名字一致就可以了。

    需要丰富枚举定义:

    /**////


    /// 性别
    ///

    public enum Sex:int
    {   
        /**////
        /// 男
        ///

        Male = 'M',
        /**////
        /// 女
        ///

        Female = 'W',
        /**////
        /// 不限
        ///

        NotRestrict = 'A'
    }
    这样虽然2的问题解决了,1、3还是没有解决。   
    解决的办法是,使用  

    System.Enum.GetValues(typeof(sex));  
    来获得所有的枚举值,然后用foreach调用:

    ddlSex.Items.Clear();
    foreach(Sex sex1 in System.Enum.GetValues(typeof(Sex)))
    {
        ListItem item = new ListItem(sex1.ToString(),((char)sex1).ToString());
        ddlSex.Items.Add(item);
    }
    这样1,3的问题就解决了!美中不足的是列表项显示的是英文,如果想要解决也未尝不可:

把枚举的项改成中文的(-_-!,这个也太.......)
使用 反射+特性(Attribute)解决!
3。最终解决办法!

    首先,给枚举值加上特性描述

    public enum Sex:int
    {
        [Description("男")]
        Male = 'M',
        [Description("女")]
        Female = 'W',
        [Description("不限")]
        NotRestrict = 'A'
    }
    然后使用反射来读这个值:

 

函数:使用(反射+特征)列出某个枚举变量及其描述信息

    /**////


    /// 获得某个Enum类型的绑定列表
    ///

    /// 枚举的类型,例如:typeof(Sex)
    ///
    /// 返回一个DataTable
    /// DataTable 有两列:    "Text"    : System.String;
    ///                        "Value"    : System.Char
    ///

    public static DataTable EnumListTable(Type enumType)
    {
        if(enumType.IsEnum != true)
        {    //不是枚举的要报错
            throw new InvalidOperationException();
        }

        //建立DataTable的列信息
        DataTable dt = new DataTable();
        dt.Columns.Add("Text",typeof(System.String));
        dt.Columns.Add("Value",typeof(System.Char));
                   
        //获得特性Description的类型信息
        Type typeDescription = typeof(DescriptionAttribute);

        //获得枚举的字段信息(因为枚举的值实际上是一个static的字段的值)
        System.Reflection.FieldInfo[] fields = enumType.GetFields();
       
        //检索所有字段
        foreach(FieldInfo field in fields)
        {
            //过滤掉一个不是枚举值的,记录的是枚举的源类型
            if(field.FieldType.IsEnum == true)
            {
                DataRow dr = dt.NewRow();

                // 通过字段的名字得到枚举的值
                // 枚举的值如果是long的话,ToChar会有问题,但这个不在本文的讨论范围之内
                dr["Value"] = (char)(int)enumType.InvokeMember(field.Name,BindingFlags.GetField,null,null,null);

                //获得这个字段的所有自定义特性,这里只查找Description特性
                object[] arr = field.GetCustomAttributes(typeDescription,true);
                if(arr.Length > 0)
                {
                    //因为Description这个自定义特性是不允许重复的,所以我们只取第一个就可以了!
                    DescriptionAttribute aa = (DescriptionAttribute)arr[0];
                    //获得特性的描述值,也就是‘男’‘女’等中文描述
                    dr["Text"] = aa.Description;
                }
                else
                {
                    //如果没有特性描述(-_-!忘记写了吧~)那么就显示英文的字段名
                    dr["Text"] = field.Name;
                }
                dt.Rows.Add(dr);
            }
        }
       
        return dt;
    }
   
    使用方法如下:

    DataTable dt = EnumListTable(typeof(Sex));
    ddlSex.DataSource = dt;
    ddlSex.DataTextField = "Text";
    ddlSex.DataValueField = "Value";
  
    怎么样?方便吧?而且这个是通用的函数,适合于所有Enum,
    前提条件是枚举值的所占的空间大小最好不要超过int。还有就是记得写描述的值,呵呵。

来自:http://www.cnblogs.com/yzxchoice/archive/2006/09/29/518122.html

 

本文作者:xbf321 来源:http://www.cnblogs.com/xbf321/
CIO之家 www.ciozj.com 微信公众号:imciow
   
免责声明:本站转载此文章旨在分享信息,不代表对其内容的完全认同。文章来源已尽可能注明,若涉及版权问题,请及时与我们联系,我们将积极配合处理。同时,我们无法对文章内容的真实性、准确性及完整性进行完全保证,对于因文章内容而产生的任何后果,本账号不承担法律责任。转载仅出于传播目的,读者应自行对内容进行核实与判断。请谨慎参考文章信息,一切责任由读者自行承担。
延伸阅读