现在的位置: 首页 > 综合 > 正文

c#枚举类型在web控件CheckBoxList,RadioButtonList,DropDownList中的应用

2012年11月09日 ⁄ 综合 ⁄ 共 5433字 ⁄ 字号 评论关闭

   在做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 { getset; }

        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 <= 0continue;

                var li = new ListItem
                             {
                                 Value 
=
                                     Convert.ChangeType(
                                         enumType.InvokeMember(fi.Name, BindingFlags.GetField, 
nullnullnull),
                                         
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 { getset; }
    }

 

 

 

在可以下载的代码包中我已经分别实现了  CheckBoxList,RadioButtonList,DropDownList控件和枚举的整合自定义控件。

分别是 EnumCheckBoxList,EnumRadioButtonList,EnumSelect

 

Demo界面

 

 在可下载的代码包中对这三个控件都有demo演示的,可以直接运行,VS2008编写

以下是全部代码,可以直接下载

/Files/szp1118/WebApplication.rar 

 

 

抱歉!评论已关闭.