type mvc example c# asp.net-mvc asp.net-mvc-3 razor mvc-editor-templates

c# - mvc - html helpers checkbox



¿Cómo puedo hacer que Html.CheckBoxFor() trabaje en un campo de cadena? (4)

Estoy usando ASP.NET MVC3 con Razor y C #. Estoy creando un generador de formularios, así que tengo un modelo que tiene una colección del siguiente objeto:

public class MyFormField { public string Name { get; set; } public string Value { get; set; } public MyFormType Type { get; set; } }

MyFormType es solo una enumeración que me dice si el campo de formulario es una casilla de verificación, o un cuadro de texto, o una carga de archivo, o lo que sea. Mi plantilla de editor se ve algo así (ver el comentario):

~ / Views / EditorTemplates / MyFormField.cshtml

@model MyFormField @{ switch (Model.Type) { case MyFormType.Textbox: @Html.TextBoxFor(m => m.Value) case MyFormType.Checkbox: @Html.CheckBoxFor(m => m.Value) // This does not work! } }

Intenté convertir / convertir m.Value en bool en la expresión lambda para CheckBoxFor (), pero eso arrojó un error. Simplemente crearía manualmente una entrada de casilla de verificación, pero CheckBoxFor () parece hacer dos cosas que parece que no puedo replicar:

  1. Crea una entrada oculta que de alguna manera se llena con la casilla de verificación. Esto parece ser lo que recoge el encuadernador modelo.
  2. Genera el nombre del objeto para que el archivador del modelo obtenga el valor en la propiedad correcta.

¿Alguien sabe cómo evitar el uso de CheckBoxFor () en una cadena, o una forma de replicar su funcionalidad de forma manual, para que yo pueda hacer que esto funcione?


Use la casilla de verificación, esta forma simple funciona bien

@Html.CheckBox("IsActive", Model.MyString == "Y" ? true : false)


También puede agregar una propiedad en su viewmodel:

public class MyFormField { public string Name { get; set; } public string Value { get; set; } public bool CheckBoxValue { get { return Boolean.Parse(Value); } } public MyFormType Type { get; set; } }

Tu punto de vista sería algo como esto:

@model MyFormField @{ switch (Model.Type) { case MyFormType.Textbox: @Html.TextBoxFor(m => m.Value) case MyFormType.Checkbox: @Html.CheckBoxFor(m => m.CheckBoxValue) // This does work! } }

Utilice Boolean.TryParse si desea evitar excepciones.


Una forma es crear su propio método de extensión htmlhelper.

public static MvcHtmlString CheckBoxStringFor<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, string>> expression) { // get the name of the property string[] propertyNameParts = expression.Body.ToString().Split(''.''); string propertyName = propertyNameParts.Last(); // get the value of the property Func<TModel, string> compiled = expression.Compile(); string booleanStr = compiled(html.ViewData.Model); // convert it to a boolean bool isChecked = false; Boolean.TryParse(booleanStr, out isChecked); TagBuilder checkbox = new TagBuilder("input"); checkbox.MergeAttribute("id", propertyName); checkbox.MergeAttribute("name", propertyName); checkbox.MergeAttribute("type", "checkbox"); checkbox.MergeAttribute("value", "true"); if (isChecked) checkbox.MergeAttribute("checked", "checked"); TagBuilder hidden = new TagBuilder("input"); hidden.MergeAttribute("name", propertyName); hidden.MergeAttribute("type", "hidden"); hidden.MergeAttribute("value", "false"); return MvcHtmlString.Create(checkbox.ToString(TagRenderMode.SelfClosing) + hidden.ToString(TagRenderMode.SelfClosing)); }

El uso es el mismo que el de CheckBoxFor (e.Value es una cadena)

@Html.CheckBoxStringFor(e => e.Value)


Tuve este problema también pero no pude modificar el modelo de vista. Intenté la solución mdm20s pero, como sospechaba, no funciona en las propiedades de la colección (no agrega los índices a los nombres y las identificaciones como los helpers html nativos). Para superar esto, puede usar Html.CheckBox en su lugar. Agrega los índices adecuados y puede pasar el valor de la casilla usted mismo.

Si realmente desea usar una expresión, siempre puede escribir un contenedor similar a mdm20s, pero reemplace todo después de TryParse con return Html.CheckBox("propertyName", isChecked) . Obviamente, deberá agregar también using System.Web.Mvc.Html .