关于在MVC中生成下拉框的各种场景应用c

    在建设网站当中,生成下拉框本来是一件非常微不足道的事,但是在实际应用当中,我常常会碰到这样的一个场景:刚开始设计时仅固定为几个下拉选项,但是经过几次迭代和需求更改之后,这个下拉选项会不断地被要求改来改去。

当然,我们希望这个下拉框是动态读取数据库中的数据,并实现动态的后台可视化管理,但有些场景下并不会提供一张表数据。

        所以在一次开发中,我突然冒出一个想法。借用类似Dictionary的键值映射关系,因为下拉框元素也刚好可以看成这样的键-值对的形式。

    所以我自定义了一个映射的类如下:

   <span style="font-family:Courier New;">public class MapEntity
    {
        #region 属性
        /// <summary>
        /// 键
        /// </summary>
        public long Key { set; get; }

        /// <summary>
        /// 值
        /// </summary>
        public string Value { get; set; }

        /// <summary>
        /// 是否启用
        /// </summary>
        public bool Enable { get; set; }
        #endregion

        #region 构造方法
        /// <summary>
        /// 默认
        /// </summary>
        public MapEntity() { }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="key">主键</param>
        /// <param name="value">值</param>
        /// <param name="enable">是否启用标志, 默认启用</param>
        public MapEntity(long key, string value, bool enable = true)
        {
            this.Key = key;
            this.Value = value;
        }
        #endregion
    }</span>


因为在这种景中,所的供的下拉选项仅仅是几种状态或是各种选项,这个状态选项又是跟其它的业务相关联的,故定义一个枚举,示例如下:

     <span style="font-family:Courier New;">public enum ActiveStatusEnum : int
    {
        /// <summary>
        /// 未审核
        /// </summary>
        [Description("未审核")]
        UnAudit = 1,


        /// <summary>
        /// 等待
        /// </summary>
        [Description("等待")]
        Wait = 2,


        /// <summary>
        /// 就绪
        /// </summary>
        [Description("就绪")]
        Ready = 3,


        /// <summary>
        /// 开始
        /// </summary>
        [Description("开始")]
        Start = 4,


        /// <summary>
        /// 完成
        /// </summary>
        [Description("完成")]
        Finish = 5,


        /// <summary>
        /// 停止
        /// </summary>
        [Description("停止")]
        Stop = -1
    }</span>


然后写一个辅助类,封装 方法:

    <span style="font-family:Courier New;">public class MapHelper
    {
        public static MapEntity[] WorkList = new MapEntity[] { 
            new MapEntity( (int)ActiveStatusEnum.UnAudit, "未审核" ),
            new MapEntity( (int)ActiveStatusEnum.Wait, "等待" ),
            new MapEntity( (int)ActiveStatusEnum.Ready, "准备" ),
            new MapEntity( (int)ActiveStatusEnum.Start, "开始" ),
            new MapEntity( (int)ActiveStatusEnum.Finish, "完成" ),
            new MapEntity( (int)ActiveStatusEnum.Stop, "终止", false),
        };

        #region 生成下拉框元素集合
        /// <summary>
        /// 生成下拉框元素集合
        /// </summary>
        /// <param name="fillArray"></param>
        /// <param name="pId"></param>
        /// <param name="IsNeedAll"></param>
        /// <returns></returns>
        public static List<SelectListItem> GetDropDownList(MapEntity[] fillArray, long pId, bool IsNeedAll = false )
        {
            List<SelectListItem> ReturnObj = new List<SelectListItem>();

            if (pId == Int32.MinValue) //如果等于最小值,则直接返回
            {
                return ReturnObj;
            }

            foreach (var item in fillArray) //遍历数组元素生成下拉框
            {
                SelectListItem ItemObj = new SelectListItem();
                ItemObj.Text = item.Value;
                ItemObj.Value = item.Key.ToString();
                ItemObj.Selected = item.Key == pId;
                ReturnObj.Add(ItemObj);
            }

            if (IsNeedAll) //是否需要插入全部选项
            {
                SelectListItem ItemObj = new SelectListItem();
                ItemObj.Text = "全部";
                ItemObj.Value = "-1";
                ItemObj.Selected = pId == -1;
                ReturnObj.Add(ItemObj);
            }

            return ReturnObj;
        }
        #endregion


        #region 通过
        /// <summary>
        /// 通过键 获取映射值
        /// </summary>
        /// <param name="fillArray">集合对象</param>
        /// <param name="key">指定键</param>
        /// <param name="IsIgnoreEnable">是否忽略"是否启用"选项,默认否</param>
        /// <returns></returns>
        public static string GetMappingValueByKey(MapEntity[] fillArray, long key, bool IsIgnoreEnable = false)
        {
            foreach (var item in fillArray)
            {
                if (item.Key == key)
                {
                    if ( ( !IsIgnoreEnable && item.Enable ) || IsIgnoreEnable  )
                    {
                        return item.Value;
                    }
                }
            }
            return string.Empty;
        }

        /// <summary>
        /// 通过键 获取映射值
        /// </summary>
        /// <param name="fillArray">集合对象</param>
        /// <param name="Value">值</param>
        /// <param name="IsIgnoreEnable">是否忽略"是否启用"选项,默认否</param>
        /// <param name="IsIgnoreCase">是否忽略大小写,默认否</param>
        /// <returns>如果集合中的键存在-999,则不适合此方法</returns>
        public static long GetMappingKeyByValue(MapEntity[] fillArray, string Value, bool IsIgnoreCase = false, bool IsIgnoreEnable = false)
        {
            if (string.IsNullOrEmpty(Value))
            {
                return -999;
            }

            foreach (var item in fillArray)
            {
                if (IsIgnoreCase)
                {
                    //忽略大小写
                    if (item.Value.ToLower().Equals(Value.ToLower()))
                    {
                        if ((!IsIgnoreEnable && item.Enable) || IsIgnoreEnable)
                        {
                            return item.Key;
                        }
                    }
                }
                else
                {
                    //不忽略大小写
                    if (item.Value.Equals(Value))
                    {
                        if ((!IsIgnoreEnable && item.Enable) || IsIgnoreEnable)
                        {
                            return item.Key;
                        }
                    }
                }
            }

            return -999;
        }
        #endregion
    }</span>


最后调用时,如下:

 <span style="font-family:Courier New;"> public class HomeController : Controller
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            ViewData["DDList"] = MapHelper.GetDropDownList(
                MapHelper.WorkList, (int)ActiveStatusEnum.UnAudit);

            return View();
        }

    }</span>


所以在下次进行变更的时候,只需要设置Enabled属性,可以设置启用或者不启用,也可以随时添加新的选项。这样非常的灵活方便。


当然,这里其实可以有另外的一种方法,那就是通过反射机制。代码如下:

     <span style="font-family:Courier New;">   /// <summary>
        /// 
        /// </summary>
        /// <param name="EnumType">枚举对象的类型</param>
        /// <param name="pId">指定的枚举名称</param>
        /// <param name="IsNeedAll">是否需要添加全部选项</param>
        /// <returns></returns>
        public static List<SelectListItem> GetDropDownList(Type EnumType, string pId, bool IsNeedAll = false)
        {
            List<SelectListItem> ResultObj = new List<SelectListItem>();

            //获取当前对象类型的所有成员
            MemberInfo[] MemberArray = EnumType.GetMembers()
                .Where(s => s.MemberType.Equals(MemberTypes.Field) && !s.Name.Equals("value__")).ToArray();

            bool IsFind = false;
            foreach (var memberItem in MemberArray)
            {
                //获取当前成员的自定义特性
                IEnumerable<CustomAttributeData> CustomArray = memberItem.CustomAttributes;

                SelectListItem SelObj = new SelectListItem();

                foreach(var customItem in CustomArray)
                {
                    //这里因为只设置了DescriptionAttribute,所以在读取第一条后直接跳出
                    SelObj.Text = customItem.ConstructorArguments[0].Value.ToString();
                    break;
                }

                SelObj.Value = memberItem.Name;
                SelObj.Selected = IsFind = memberItem.Name.Equals(pId);
                ResultObj.Add(SelObj);
            }

            if (IsNeedAll)
            {
                if (IsNeedAll) //是否需要插入全部选项
                {
                    SelectListItem ItemObj = new SelectListItem();
                    ItemObj.Text = "全部";
                    ItemObj.Value = "-1";
                    ItemObj.Selected = !IsFind;
                    ResultObj.Add(ItemObj);
                }
            }

            return ResultObj;
        }</span>



在调用时,只需要传入如下参数示例:


ViewData["DDList2"] = MapHelper.GetDropDownList(typeof(ActiveStatusEnum), ActiveStatusEnum.UnAudit.ToString());


虽然反射机制也是可以实现,但是却少了一些控制上的灵活性以及多了一些性能上的损耗,相比之下,自定义的映射类,可以自定义属性控制开关,添加额外的信息等等。


这只是在写代码过程中一些小的思考,希望自己能有更多的这样的思考,积少成多!加油!




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值