在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
在做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>
编译完之后可以从工具箱的自定义组件中拖拉到页面中
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
Demo界面 在可下载的代码包中对这三个控件都有demo演示的,可以直接运行,VS2008编写 以下是全部代码,可以直接下载 /Files/szp1118/WebApplication.rar
|
请发表评论