用反射+特性列出所有的枚舉變量及其描述信息,綁定到DropDownList上

 

 

1。問題

 

    在設計實體類的時候,通常我們會把某些字段設置爲枚舉值,例如性別:

 

public enum Sex:int

{

    Male = 'M',Female = 'W',NotRestrict = 'A'

}

 

    這樣好處不用說,通常是爲了直觀的考慮,還有限制輸入的好處;如果強制用int轉換,還以用System.Enum.IsDefined() 來判斷枚舉是否被定義,但是麻煩的是在界面UI上綁定的時候,我們通常要這樣寫:

 

    <asp:DropDownList Runat="server" id="ddlSex">

        <asp:ListItem Value="M">男</asp:ListItem>

        <asp:ListItem Value="W">女</asp:ListItem>

        <asp:ListItem Value="A">不限</asp:ListItem>

    </asp:DropDownList>

 

    然後如果要取得枚舉的值,則:

 

    Sex sex = (Sex)ddlSex.SelectedValue.ToCharArray()[0];

    取值的時候其實沒有多大問題,問題在UI上面

首先要知道所有枚舉的值:例如'W','M','A'等

需要知道枚舉值的名稱,通常使用中文,例如'男','女'等,界面設計人員無法確定使用什麼中文描述。

枚舉的項目改變的時候,所有的綁定都需要改變。

2。解決了嗎?

 

    解決描述的問題很簡單,使用XML文檔就可以了。

    只要在項目輸出的時候輸出XML文檔,並且文檔的名字跟DLL的名字一致就可以了。

 

    需要豐富枚舉定義:

    /// <summary>

    /// 性別

    /// </summary>

    public enum Sex:int

    {    

        /// <summary>

        /// 男

        /// </summary>

        Male = 'M',

        /// <summary>

        /// 女

        /// </summary>

        Female = 'W',

        /// <summary>

        /// 不限

        /// </summary>

        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'

    }

    然後使用反射來讀這個值:

 

 

    /// <summary>

    /// 獲得某個Enum類型的綁定列表

    /// </summary>

    /// <param name="enumType">枚舉的類型,例如:typeof(Sex)</param>

    /// <returns>

    /// 返回一個DataTable

    /// DataTable 有兩列:    "Text"    : System.String;

    ///                        "Value"    : System.Char

    /// </returns>

    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/zellzhang/archive/2005/10/17/256576.html

發佈了56 篇原創文章 · 獲贊 6 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章