Dot-Net

如何在 ASP.NET MVC 中創建 CheckBoxListFor 擴展方法?

  • August 15, 2013

我知道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());
}

引用自:https://stackoverflow.com/questions/3889397