2011-08-25 11 views
11

estoy usando ASP.NET MVC3 con la maquinilla de afeitar y C#. Estoy haciendo un constructor de la forma de clases, así que tengo un modelo que tiene una colección de los siguientes objetos:¿Cómo puedo hacer Html.CheckBoxFor() funciona en un campo de cadena?

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

MyFormType es sólo una enumeración que me dice que si el campo de formulario es una casilla de verificación o de texto, o carga de archivos, o lo que sea. Mi editor de plantillas se ve algo como esto (ver el comentario):

~/Vistas/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! 
    } 
} 

Probé a presión/conversión de la m.Value a un bool en la expresión lambda para CheckBoxFor(), pero eso arrojó un error. Me acaba de construir manualmente una entrada de casilla, pero CheckBoxFor() parece hacer dos cosas que me parece que no puede replicar:

  1. crea un campo oculto que de alguna manera se rellena por la casilla de verificación. Esto parece ser lo que recoge el encuadernador modelo.
  2. genera el nombre de formar el objeto de modo que el aglutinante modelo obtiene el valor en el derecho de propiedad.

¿Alguien sabe una forma de evitar el uso de CheckBoxFor() en una cuerda, o una manera de replicar su funcionalidad de forma manual, por lo que puedo hacer este trabajo?

Respuesta

11

También puede añadir una propiedad en su modelo de vista:

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

Su punto de vista sería sea ​​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! 
    } 
} 

Use Boolean.TryParse si quiere evitar excepciones.

+0

¡Gracias!¡Esto resolvió mi problema que estaba teniendo! – AustinT

10

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 CheckBoxFor helper (e.Value es una cadena)

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

Creo que envolver la propiedad es la forma más fácil de la manera/limpiador en esta situación, pero voy a votar tienes para esta explicación. He estado buscando el código de las dos primeras secciones de tu método, ¡así que gracias por esa parte! – jrizzo

0

tuve este problema también, pero fue incapaz de modificar el modelo de vista. Intentado solución mdm20s pero como sospechaba que no funciona en las propiedades de recogida (que no aporta los índices para los nombres y los identificadores como los ayudantes nativos html). 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 del TryParse con return Html.CheckBox("propertyName", isChecked). Obviamente, necesitará agregar using System.Web.Mvc.Html también.

3

utilizar la casilla, esta forma tan simple funciona bien

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

¿No necesita el '? true: parte falsa 'Model.MyString ==" Y "' ya es un booleano. – Alexander

Cuestiones relacionadas