tutorial net mvc example entre ejemplos diferencias asp .net asp.net asp.net-mvc checkboxlist

example - ¿Cómo crear un método de extensión CheckBoxListFor en ASP.NET MVC?



web forms c# ejemplos (4)

Puede que le interese el artículo de CheckBoxList Helper para MVC de Jeremiah Clark (desafortunadamente está fechado en noviembre de 2008 y se refiere a MVC 1).

Sé que hay un método de extensión ListBoxFor entre los métodos de extensión de ayuda de ASP.NET MVC Html, pero siempre pensé que una lista de casillas de verificación es más fácil de usar que un cuadro de lista.

Había un control CheckBoxList muy conveniente en los viejos WebForms antiguos, pero obviamente ahora está fuera de lugar.

La pregunta es, ¿por qué no hay forma en ASP.NET MVC de crear una lista de casilla de verificación? ¿Cómo puedo escribir mi propio método de extensión que crea una lista de casilla de verificación y se comporta de manera similar a ListBoxFor ?


Si bien los empleados de Microsoft son probablemente los únicos que pueden responder por qué dicho método auxiliar no existe, podría intentar:

Modelo:

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

Controlador:

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

Ver:

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

Como puede ver, EditorFor manejará todo lo que sea necesario.


Todavía estoy experimentando, pero parece que se lleva bien con la carpeta predeterminada y persiste en las selecciones del usuario después de la publicación ... ¿Campos ocultos, en realidad? ¿volará esto en html5? Esto parece una locura, pero preferiría hacer esto antes que pegarle a mi DB por listas desplegables y listas de casillas simplemente porque ModelState.IsValid es falso.

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


Aquí hay un HtmlHelper fuertemente tipado para CheckBoxListFor que maneja los elementos seleccionados como una matriz en su modelo de viewdata. Elegí no envolver los métodos Html.CheckBox o Html.CheckBoxFor ya que no quiero los campos "falsos" ocultos en mi lista de casillas de verificación.

Por favor, siéntete libre de mejorar esto y volver a publicar :-)

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