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

来源:互联网 发布:淘宝引流手机软件 编辑:程序博客网 时间:2024/06/06 09:25

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

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

        所以在一次开发中,我突然冒出一个想法。借用类似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());


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


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




1 0