在做web项目的时候经常使用CheckBoxList,RadioButtonList,DropDownList控件,对于这些控件的数据源如果需要客户动态维护的一般存于数据库中,但是大量的这些控件的数据源并不需要提供可视化的动态维护,如果直接在页面中写死则会存在重用性不强,后台代码编写容易出错等问题。现在我整理成使用枚举实现,重用性好,编写代码使用枚举值比较,不容易出错,虽然通过反射实现,性能并不是最好,但是个人觉得牺牲这么一点点性能还是值得的。具体代码分析如下:
首先是枚举的定义,这里定义了国家类型的枚举
/// <summary>
/// 国家
/// </summary>
public enum Country
{
[ListItemText("中国")]
China = 1,
[ListItemText("美国")]
America = 2,
[ListItemText("德国")]
Germany = 3,
[ListItemText("英国")]
England = 4,
[ListItemText("法国")]
France = 5,
[ListItemText("日本")]
Japan = 6
}
该枚举中的枚举值,即1,2,3,4,5,6对应于CheckBoxList,RadioButtonList,DropDownList中的ListItem的value,即值。
枚举中的特性 ListItemText 对应于ListItem中的text。
输出到客户端的html如下(DropDownList示例)
<select name="EnumSelect1" id="EnumSelect1">
<option selected="selected" value="1">中国</option>
<option value="2">美国</option>
<option value="3">德国</option>
<option value="4">英国</option>
<option value="5">法国</option>
<option value="6">日本</option>
</select>
定义继承自DropDownList的自定义控件,用于实现该枚举类型和DropDownList的整合。
EnumSelect 类
public class EnumSelect : System.Web.UI.WebControls.DropDownList
{
/// <summary>
/// 在页面中设置该控件的枚举类型名称,必须设置
/// </summary>
public string EnumTypeName { get; set; }
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (Page.IsPostBack) return;
var a = Assembly.Load("WebApplication");
if (string.IsNullOrEmpty(EnumTypeName))
throw new Exception("必须设置属性EnumTypeName的值");
var t = a.GetType(EnumTypeName);
var list = Util.GetListItemFromEnum<int>(t);
foreach (ListItem li in list)
{
this.Items.Add(li);
}
}
}
该类只需要设置一个属性EnumTypeName 即枚举的具体类型就可以(类型为全名,需要包含命名空间)
在页面中使用该控件设置EnumTypeName 属性值:
<cc1:EnumSelect ID="EnumSelect1" runat="server" EnumTypeName="WebApplication.Country">
</cc1:EnumSelect>
编译完之后可以从工具箱的自定义组件中拖拉到页面中
![](../../2012UploadFiles/12/Dezai20121229101155.gif)
EnumSelect1类中的Util类如下:
Util 类
public class Util
{
/// <summary>
/// 根据一个枚举类型转化成ListItemCollection
/// </summary>
/// <param name="enumType">枚举类型</param>
/// <returns></returns>
public static ListItemCollection GetListItemFromEnum<T>(Type enumType)
{
var list = new ListItemCollection();
if (enumType.IsEnum != true){
throw new Exception("方法GetListItemFromEnum只能接受枚举类型");
}
var typeText = typeof(ListItemTextAttribute);
//获得枚举的字段信息(因为枚举的值实际上是一个static的字段的值)
var fields = enumType.GetFields();
foreach (var fi in fields)
{
if (!fi.FieldType.IsEnum) continue;
//获得这个字段的所有自定义特性,这里只查找ListItemTextAttribute特性
var arr = (ListItemTextAttribute[])(fi.GetCustomAttributes(typeof(ListItemTextAttribute), true));
if (arr.Length <= 0) continue;
var li = new ListItem
{
Value =
Convert.ChangeType(
enumType.InvokeMember(fi.Name, BindingFlags.GetField, null, null, null),
typeof (T)).ToString()
};
//因为ListItemTextAttribute这个自定义特性是不允许重复的,所以我们只取第一个就可以了!
var a = (ListItemTextAttribute)arr[0];
//获得特性的描述值,也就是‘男’‘女’等中文描述
li.Text = a.Text;
list.Add(li);
}
return list;
}
/// <summary>
/// 根据枚举值获得指定的ListItemTextAttribute的值
/// </summary>
/// <typeparam name="T">必须为枚举类型</typeparam>
/// <param name="e"></param>
/// <returns></returns>
public static string GetEnumListItemText<T>(T e)
{
var t = typeof(T);
if (!t.IsEnum)
{
throw new Exception("泛型参数必须为枚举类型");
}
var mis = t.GetMember(e.ToString());
if (mis.Length != 1)
{
throw new Exception("无法找到该枚举属性或者该枚举属性数量大于1");
}
var arr = (ListItemTextAttribute[])mis[0].GetCustomAttributes(typeof(ListItemTextAttribute), false);
if (arr.Length == 0)
{
throw new Exception("未指定该枚举属性的Text值");
}
return arr[0].Text;
}
}
Util类有两个方法:
1.GetListItemFromEnum方法: 传入一个具体的枚举类型,返回 CheckBoxList,RadioButtonList,DropDownList控件需要的数据源ListItemCollection。
2.GetEnumListItemText方法: 传入一个枚举值,比如Country.China,返回的是具体的text,这里返回 “中国”。
如果是根据具体的选中项来取得文本值,则代码如下
var province = string.Empty;
if (!string.IsNullOrEmpty(EnumRadioButtonList1.SelectedValue))
province = Util.GetEnumListItemText<Province>((Province)(int.Parse(EnumRadioButtonList1.SelectedValue)));
最后还有一个重要的特性类没有介绍,具体代码如下:
/// <summary>
/// 枚举类型的字段 ListItem Text 特性
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public class ListItemTextAttribute : Attribute
{
public ListItemTextAttribute(string text)
{
this.Text = text;
}
public string Text { get; set; }
}
在可以下载的代码包中我已经分别实现了 CheckBoxList,RadioButtonList,DropDownList控件和枚举的整合自定义控件。
分别是 EnumCheckBoxList,EnumRadioButtonList,EnumSelect
![](../../2012UploadFiles/12/Dezai20121229101220.gif)
http://www.cnblogs.com/szp1118/archive/2010/07/15/1778228.html
本文作者:网友 来源:网络
CIO之家 www.ciozj.com 微信公众号:imciow