Dot-Net
如何在 ASP.NET MVC 中創建 CheckBoxListFor 擴展方法?
我知道
ListBoxForASP.NET MVC Html 輔助擴展方法中有一個擴展方法,但我一直認為複選框列表比列錶框更使用者友好。舊的 WebForms 中有一個非常方便的
CheckBoxList控制項,但顯然現在已經不存在了。問題是,為什麼在 ASP.NET MVC 中沒有辦法創建複選框列表?如何編寫自己的擴展方法來創建複選框列表並以類似的方式
ListBoxFor執行?
這是 CheckBoxListFor 的強類型 HtmlHelper,它將所選項目作為視圖數據模型中的數組處理。我選擇不包裝 Html.CheckBox 或 Html.CheckBoxFor 方法,因為我不想在我的複選框列表中隱藏“假”欄位。
請隨時對此進行改進並重新發布:-)
//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()); }