.NET MVC标签扩展(checkbox,radio)

来源:互联网 发布:什么是挂机软件 编辑:程序博客网 时间:2024/06/08 16:27

      .NET  MVC里面自动绑定form表单功能(如:@Html.TextBox("Name")、@Html.Hidden("hide"),名称会自动与后台就行绑定ViewBag.Name,ViewBag,hide)很实用,但是感觉不足的就是@Html.CheckBox("check")和@Html.RadioButton("radio","1"),这两个表单只能单个进行绑定,当出现多个绑定进行选中时,用起来就相对不太方便,如下图



       想要通过集合直接绑定生成需要的多个checkbox和radiobutton,并且部分处于选中状态,还好.NET的扩展方法为我们提供了方便。扩展方法就不用多说了,就是在静态类中,建立静态方法,并且第一个参数是 (this [要扩展的对象] name),

     比如,你要给string类型扩展一个方法,要求当string长度超过10的时候只要截取前十个字符,当长度少于10的时候返回原字符串你可以这样:

namespace System{    public static class StringExtension    {       public static string SubTen(this string sourceStr) {             if(!string.IsNullOrEmpty(sourceStr)&&sourceStr.Length>10){                return sourceStr.Substring(0,10);            }            return sourceStr;        }    }}</span>
   调用的时候如下所示:
 string SS = "AASSSSSSSSSSSSSS";  var SSS = SS.SubTen();

      这样当字符串长度大于10 的时候就会取出前十个字符。

      好了,扩展方法就说到这里,现在进入正题,对HtmlHelper要扩展四个方法,分别是生成checkbox集合,checkbox单个,radio集合和radio单个。

       方法如下,因为checkbox和radio只是type类型不同,因此,他们可以用同样的方法,只是传值的时候把类型传入进行判断就可以了。

private static IDictionary<string, object> CopyAll(this IDictionary<string, object> dicSor)        {            Dictionary<string, object> dicDst = new Dictionary<string, object>();            foreach (var item in dicSor)            {                dicDst.Add(item.Key, item.Value);            }            return dicDst;        }
这里的dictionary的扩展是方便循环的时候使用。
        /// <summary>        /// 扩展checkbox和radio        /// </summary>        /// <param name="targtname">后台的取值</param>        /// <param name="itype">标签类型</param>        /// <param name="name">标签值name或者取后台值用到</param>        /// <param name="selectList">传入的集合</param>        /// <param name="htmlAttributes">Html标签属性</param>        /// <returns></returns>        private static MvcHtmlString RadioOrCheckBox(object targtname, string itype, string name, IEnumerable<SelectListItem> selectList, object htmlAttributes)        {            //不存在绑定值则返回空            if (string.IsNullOrEmpty(name) || (targtname == null && selectList == null))            {                return MvcHtmlString.Create("");            }            //if (htmlHelper.ViewData.ContainsKey(name)) {            //    name = htmlHelper.ViewData[name].ToString();            //}            string selectValues = "";            Object selectedValues = null;            HashSet<string> ckSet = new HashSet<string>();//用于存储选定值,不添加重复项            List<SelectListItem> listSelectListItem = new List<SelectListItem>(); //这里可以不新建对象直接用selectList,这样下面画-----横线的代码也可以省略            if (targtname != null)           //后台取值赋值            {               // selectList = new List<SelectListItem>();//---------                if (targtname.GetType() != typeof(SelectList)) //后台传入ViewBag.AAA=new SelectList()类型                {                    return MvcHtmlString.Create("");                }                SelectList slItemlist = targtname as SelectList;                selectedValues = slItemlist.SelectedValue ?? ""; //要选中的值                if (selectedValues != null)                {                    selectValues = selectedValues.ToString();                    string[] tempStr = selectValues.Split(','); //多个选中用逗号隔开                    //Array.IndexOf(tempStr, "");                    ckSet = new HashSet<string>(tempStr);                }                foreach (var item in slItemlist)                {                    if (ckSet.Contains(item.Value))                    {                        item.Selected = true; //选中值设为true                    }                    listSelectListItem.Add(item);                }            }            //验证绑定的对象            if (listSelectListItem.Count <= 0 && selectList != null && selectList.Count() > 0)//--------------            {                listSelectListItem.AddRange(selectList);//--------            }            string id = string.Empty;  //checkbox一般不带id,这几行代码其实没用            IDictionary<string, object> htmlAttributesdic = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);            if (htmlAttributesdic.ContainsKey("id"))            {                id = htmlAttributesdic["id"].ToString();                htmlAttributesdic.Remove("id");            }            htmlAttributesdic.Add("type", itype);//生成的类型,是checkbox或者是radio            htmlAttributesdic.Add("name", name);            StringBuilder sbHtml = new StringBuilder();            foreach (SelectListItem selectItem in listSelectListItem)            {                IDictionary<string, object> newDicAttributes = htmlAttributesdic.CopyAll();                newDicAttributes.Add("value", selectItem.Value);                if (selectItem.Selected) //为true则处于选中状态                {                    newDicAttributes.Add("checked", "checked");                }                TagBuilder tagBuilder = new TagBuilder("input");//新建input表单                tagBuilder.MergeAttributes<string, object>(newDicAttributes); //添加表单属性                string inputAllHtml = tagBuilder.ToString(TagRenderMode.SelfClosing); //TagRenderMode枚举,自关闭类型如:<input />                string containerFormat = @"<label> {0}  {1}</label>"; //外层套上label可以点击文字的时候选中按钮,如果想要水平垂直居中最后在加上<P></P>标签                           sbHtml.AppendFormat(containerFormat,                   inputAllHtml, selectItem.Text);            }            return MvcHtmlString.Create(sbHtml.ToString());        }

      因为这是绑定集合数据,因此targtname和selectList参数不能同时为空,默认是以targtname绑定的数据优先,当targtname存在且类型正确的时候,绑定targtname中的数据,当targtname取后台值为null的时候再判断取selectList中的值,上面的后台取值其实可以优化更通用一点,只是感觉没那么必要了,自己定的一个约定知道赋值取值一般不会出错。其他的就不多介绍了,注释里面很详细了。

真正的扩展到了,如下:

   /// <summary>        /// checkbox集合扩展        /// </summary>        /// <param name="htmlHelper"></param>        /// <param name="name">标签名称</param>        /// <param name="selectList">items</param>        /// <param name="htmlAttributes">属性html</param>        /// <returns></returns>        public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, object htmlAttributes)        {            var targtname = htmlHelper.ViewData[name];//取后台数据            return RadioOrCheckBox(targtname, "checkbox", name, selectList, htmlAttributes);        }

        /// <summary>        /// radio集合扩展        /// </summary>        /// <param name="htmlHelper"></param>        /// <param name="name">name属性</param>        /// <param name="selectList">item属性</param>        /// <param name="htmlAttributes">额外属性</param>        /// <returns></returns>        public static MvcHtmlString RadioButtonList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, object htmlAttributes)        {            var targtname = htmlHelper.ViewData[name];//取后台数据            return RadioOrCheckBox(targtname, "radio", name, selectList, htmlAttributes);        }

这样,放到静态类的静态方法就可以正常使用了,注意这个命名空间,最好用System.Web.Mvc.Html这样与其他的扩展方法命名空间一致,那样省去我们在页面还要单独引用命名空间。

namespace System.Web.Mvc.Html{    public static class InputExtension    {    }}
在html页面中使用方式如下:

  @Html.CheckBoxList("Drop",null, new {@class = "tclass", @style = "" }) <br />       @Html.RadioButtonList("Drop",null, new {@class = "tclass", @style = "" })<br/>

接下来扩展单个标签的radio和checkbox标签,方便的在循环的时候使用,少了对是否选中的判断,只要value值与是否选中的值一致,那么他就处于选中状态,不一致则不选中,不用再判断if(){}else if(){},

代码如下:

        /// <summary>        /// 单标签为了在循环的时候使用方便        /// </summary>        /// <param name="itype">标签类型</param>        /// <param name="name">标签name属性</param>        /// <param name="value">标签value值</param>        /// <param name="showText">radio或者checkbox要显示的名字</param>        /// <param name="htmlAttributes">标签的其他属性</param>        /// <param name="selectValue">选中的值</param>        /// <returns></returns>        private static MvcHtmlString RadioOrCheckBoxItem(string itype,string name, string value, string showText, object htmlAttributes, string selectValue = "")        {            //生成<input type='radio' name ='name' value='value'> name和value不能为空            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value))            {                return MvcHtmlString.Create("");            }            StringBuilder sbHtml = new StringBuilder();            IDictionary<string, object> htmlAttributesdic = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);            htmlAttributesdic.Add("type", itype); //标签类型radio或者checkbox            htmlAttributesdic.Add("value", value);            htmlAttributesdic.Add("name", name);            var dd = string.Compare(value, selectValue, true);            if (value.Equals(selectValue, StringComparison.OrdinalIgnoreCase)) //这里判断当value和selectValue一致,则处于选中状态            {                htmlAttributesdic.Add("checked", "checked");            }            TagBuilder tagBuilder = new TagBuilder("input");            tagBuilder.MergeAttributes<string, object>(htmlAttributesdic);            string inputAllHtml = tagBuilder.ToString(TagRenderMode.SelfClosing);            string containerFormat = @"<label> {0}  {1}</label>";                   sbHtml.AppendFormat(containerFormat,               inputAllHtml, showText);            return MvcHtmlString.Create(sbHtml.ToString());        }

这个就不解释了,和上面那个道理一样。

       /// <summary>        /// 单个checkbox扩展        /// </summary>        /// <param name="htmlHelper"></param>        /// <param name="name">name属性</param>        /// <param name="value">值</param>        /// <param name="showText">要显示的文本</param>        /// <param name="htmlAttributes">额外属性</param>        /// <param name="selectValue">选中的值</param>        /// <returns></returns>        public static MvcHtmlString CheckBoxItem(this HtmlHelper htmlHelper, string name, string value, string showText, object htmlAttributes, string selectValue = "")        {            return RadioOrCheckBoxItem("checkbox",name, value, showText, htmlAttributes, selectValue);        }

     /// <summary>        /// radio单个按钮        /// </summary>        /// <param name="htmlHelper"></param>        /// <param name="name">标签name</param>        /// <param name="value">radio值</param>        /// <param name="showText">显示的文本</param>        /// <param name="htmlAttributes">额外属性</param>        /// <param name="selectValue">选中的值</param>        /// <returns></returns>        public static MvcHtmlString RadioButtonItem(this HtmlHelper htmlHelper, string name, string value, string showText, object htmlAttributes, string selectValue = "")        {            return RadioOrCheckBoxItem("radio", name, value, showText, htmlAttributes, selectValue);        }

好了几个扩展方法写完了,下面就到了用的时候了:

MVC控制器代码:

     public ActionResult Index()        {            Dictionary<string, object> dic = new Dictionary<string, object>();            dic.Add("1", "字典一");            dic.Add("2", "字典二");            dic.Add("3", "字典三");            ViewBag.DIC = new SelectList(dic, "key", "value", "3,2");            List<DropList> listdrop = new List<DropList>(){             new DropList(){dname="自定义集合一", dvalue="one", dother="dropvalueOne"},             new DropList(){dname="自定义集合二", dvalue="two", dother="dropvalueTwo"},             new DropList(){dname="自定义集合三", dvalue="three", dother="dropvalueThree"}            };            ViewBag.Drop = new SelectList(listdrop, "dvalue", "dname", "two");            List<SelectListItem> ieitem = new List<SelectListItem>(){                  new SelectListItem(){ Selected=true, Text="不存在一", Value="sdfg"},                  new SelectListItem(){ Selected=false, Text="不存在二", Value="ryhfgh"},                  new SelectListItem(){ Selected=true, Text="不存在三", Value="yuioi"}            };            ViewBag.RRR = ieitem;          return View()}

MVC视图代码测试radio和checkbox集合:

    <fieldset>        <legend>这是测试集合</legend><br/>        <label>后台不存在ViewBag.AAAA则取 ViewBag.RRR:</label>          @Html.CheckBoxList("AAAA", ViewBag.RRR as IEnumerable<SelectListItem>,new{ style = "" })<br /><br />        <label>后台存在ViewBag.DIC:</label>        @Html.CheckBoxList("DIC", null, new { @class = "tclass", @style = "" }) <br /><br />        <label>后台存在ViewBag.Drop:</label>        @Html.RadioButtonList("Drop", null, new { @class = "tclass", @style = "" })<br /><br />    </fieldset>

生成结果如下图所示:



MVC视图单个radio和checkbox,如下:

    <fieldset>        <legend>这是测试单个</legend><br/>        <label>radio单个:</label>         @Html.RadioButtonItem("AAA", "45", "测试radio1", new { }, "415")         @Html.RadioButtonItem("AAA", "425", "测试radio2", new { }, "425")<br/><br/>        <label>checkbox单个:</label>        @Html.CheckBoxItem("BBBB", "3", "测试checkbox", new { }, "34")        @Html.CheckBoxItem("BBBB", "34", "测试checkbox", new { }, "34")         @Html.CheckBoxItem("BBBB", "35", "测试checkbox", new { }, "35")           </fieldset>

生成的结果如下图所示:


    好了,写完了,希望对大家有所帮助,有什么不对或者需要优化的地方还请大家批评指出,我会尽快改正,谢谢!





1 0