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