我知道ASP.NET MVC Html帮助程序扩展方法中有一个ListBoxFor扩展方法,但是我一直认为复选框列表比列表框更加用户友好。
在很好的旧WebForms中有一个非常方便的CheckBoxList控件,但显然这是现在的图片。
问题是,为什么ASP.NET MVC中没有办法创建一个复选框列表?如何编写自己的扩展方法,创建一个复选框列表,并以类似的方式表现ListBoxFor的行为?
解决方法
这是一个用于CheckBoxListFor的强类型的HtmlHelper,它将所选项目作为数据在viewdata模型中处理。我选择不包装Html.CheckBox或Html.CheckBoxFor方法,因为我不想在我的复选框列表中隐藏“false”字段。
请随时改进这个和转发:-)
//View <%: Html.CheckBoxListFor(model => model.FreightTypeIds,FreightTypeMultiSelectList) %> //Controller public ActionResult SomeAction(int[] FreightTypeIds) { //... return View(); } //Extension public static MvcHtmlString CheckBoxListFor<TModel,TProperty>(this HtmlHelper<TModel> htmlHelper,Expression<Func<TModel,IEnumerable<TProperty>>> expression,MultiSelectList allOptions,object htmlAttributes = null) { ModelMetadata modelMetadata = ModelMetadata.FromLambdaExpression<TModel,IEnumerable<TProperty>>(expression,htmlHelper.ViewData); // Derive property name for checkBox name string propertyName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(modelMetadata.PropertyName); // Get currently select values from the ViewData model IEnumerable<TProperty> list = expression.Compile().Invoke(htmlHelper.ViewData.Model); // Convert selected value list to a List<string> for easy manipulation IList<string> selectedValues = new List<string>(); if (list != null) { selectedValues = new List<TProperty>(list).ConvertAll<string>(delegate(TProperty i) { return i.ToString(); }); } // Create div TagBuilder divTag = new TagBuilder("div"); divTag.MergeAttributes(new RouteValueDictionary(htmlAttributes),true); // Add checkBoxes foreach (SelectListItem item in allOptions) { divTag.InnerHtml += string.Format( "<div><input type=\"checkBox\" name=\"{0}\" id=\"{1}_{2}\" " + "value=\"{2}\" {3} /><label for=\"{1}_{2}\">{4}</label></div>",propertyName,TagBuilder.CreateSanitizedId(propertyName),item.Value,selectedValues.Contains(item.Value) ? "checked=\"checked\"" : string.Empty,item.Text); } return MvcHtmlString.Create(divTag.ToString()); }