2010-10-08 2 views
15

Я знаю, что существует метод расширения ListBoxFor среди вспомогательных методов расширения ASP.NET MVC Html, но я всегда думал, что список флажков более удобен, чем список.Как создать метод CheckBoxListFor расширения в ASP.NET MVC?

Был очень удобный CheckBoxList элемент управления в старых добрых WebForms, но, очевидно, что сейчас нет изображения.

Вопрос в том, почему в ASP.NET MVC нет способа создать список флажков? Как я могу написать собственный метод расширения, который создает список флажков и ведет себя аналогичным образом ListBoxFor ведет себя?

ответ

33

Вот строго типизированный HtmlHelper для CheckBoxListFor, который обрабатывает выбранные элементы как массив в вашей модели viewdata. Я решил не обертывать методы 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()); 
} 
+0

спасибо, это, кажется, то, что я искал. Попробуй, как только я вернусь домой. – Venemo

+1

С некоторыми изменениями я успешно сделал это, чтобы работать так, как я хотел. Большое спасибо за код! :) – Venemo

+0

Мне это нравится! Мне просто интересно, как реализовать проверку (ненавязчивую) сейчас ... –

0

Вас может заинтересовать CheckBoxList Helper for MVC статья Джеремии Кларк (к сожалению, она датирована ноябрем 2008 года и касается MVC 1).

+0

Статья хорошая, но не написано с сильно типизированных HTML помощников в виду. – Venemo

1

В то время как сотрудники Microsoft, вероятно, только те, которые могут ответить, почему такой вспомогательный метод не существует, вы можете попробовать:

Модель:

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); 
    } 
} 

View :

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

Как видите, EditorFor будет обрабатывать все, что необходимо.

+0

Это хорошая идея, но, как я уже сказал, я хотел бы иметь что-то похожее на поведение «ListBoxFor». – Venemo

+0

Можете ли вы быть более конкретным? 'ListBoxFor' генерирует'