如何在ASP.NET MVC中创build一个CheckBoxListFor扩展方法?

我知道在ASP.NET MVC Html帮助器扩展方法中有一个ListBoxFor扩展方法,但我一直认为checkbox列表比列表框更方便用户使用。

在旧的WebForms中有一个非常方便的CheckBoxList控件,但显然现在已经不存在了。

问题是,为什么ASP.NET MVC中没有办法创build一个checkbox列表? 我怎么能写我自己的扩展方法,创build一个checkbox列表,并以类似的方式行为ListBoxFor行为?

这里是一个CheckBoxListFor强types的HtmlHelper,它把你select的项目作为viewdata模型中的一个数组来处理。 我select不包装Html.CheckBox或Html.CheckBoxFor方法,因为我不想在我的checkbox列表中隐藏“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()); } 

我仍然在试验,但这似乎相处的默认活页夹,坚持后发表的用户select..隐藏的领域,真的? ..这将飞在HTML5? 这感觉很疯狂,但我宁愿这样做比打我的数据库的下拉列表和checkbox列表只是因为ModelState.IsValid是错误的..

  public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, List<SelectListItem> list, string ModelCollectionName) { var sb = new StringBuilder(); if (list != null) { int i = 0; foreach (var l in list) { string collectionNameIndex = String.Format("{0}[{1}]", ModelCollectionName, i); var hiddenName = new TagBuilder("input"); hiddenName.Attributes.Add(new KeyValuePair<string, string>("type", "hidden")); hiddenName.Attributes.Add(new KeyValuePair<string, string>("name", String.Format("{0}.{1}", collectionNameIndex, "Text"))); hiddenName.Attributes.Add(new KeyValuePair<string, string>("value", l.Text)); var hiddenValue = new TagBuilder("input"); hiddenValue.Attributes.Add(new KeyValuePair<string, string>("type", "hidden")); hiddenValue.Attributes.Add(new KeyValuePair<string, string>("name", String.Format("{0}.{1}", collectionNameIndex, "Value"))); hiddenValue.Attributes.Add(new KeyValuePair<string, string>("value", l.Value)); var checkBoxTag = htmlHelper.CheckBox(String.Format("{0}.{1}", collectionNameIndex, "Selected"), l.Selected); var labelTag = new TagBuilder("label"); labelTag.Attributes.Add(new KeyValuePair<string, string>("for", String.Format("{0}.{1}", collectionNameIndex, "Name"))); labelTag.SetInnerText(l.Text); sb.Append(hiddenName); sb.Append(hiddenValue); sb.Append(checkBoxTag); sb.Append(labelTag); sb.Append("<br/>"); i++; } } return MvcHtmlString.Create(sb.ToString()); } 

虽然微软员工可能是唯一可以回答为什么不存在这种帮助方法的人,但您可以尝试:

模型:

 public class MyViewModel { public bool[] Values { get; set; } } 

控制器:

 public class HomeController : Controller { public ActionResult Index() { return View(new MyViewModel { Values = new[] { true, false, true, false } }); } [HttpPost] public ActionResult Index(MyViewModel model) { return View(model); } } 

视图:

 <% using (Html.BeginForm()) { %> <%: Html.EditorFor(x => x.Values) %> <input type="submit" value="OK" /> <% } %> 

正如你所看到的, EditorFor将处理所有需要的东西。

您可能会对Jeremiah Clark的MVC文章的CheckBoxList Helper感兴趣(不幸的是它的date是2008年11月,关注MVC 1)。