2010-06-13 21 views
13

Disculpa si se trata de un dup, mi búsqueda no arrojó nada.Elemento seleccionado en listas desplegables de Enum en ASP.net MVC

estoy usando el siguiente método para generar listas desplegables para tipos de enumeración (levantadas desde aquí: http://addinit.com/?q=node/54):

public static string DropDownList(this HtmlHelper helper, string name, Type type, object selected) 
{ 
    if (!type.IsEnum) 
     throw new ArgumentException("Type is not an enum."); 

    if(selected != null && selected.GetType() != type) 
     throw new ArgumentException("Selected object is not " + type.ToString()); 

    var enums = new List<SelectListItem>(); 
    foreach (int value in Enum.GetValues(type)) 
    { 
     var item = new SelectListItem(); 
     item.Value = value.ToString(); 
     item.Text = Enum.GetName(type, value); 

     if(selected != null) 
      item.Selected = (int)selected == value; 

     enums.Add(item); 
    } 

    return System.Web.Mvc.Html.SelectExtensions.DropDownList(helper, name, enums, "--Select--"); 
} 

Se está trabajando muy bien, excepto por una cosa. Si le doy a la lista desplegable el mismo nombre que la propiedad en mi modelo, el valor seleccionado no está configurado correctamente. Significando esto funciona:

<%= Html.DropDownList("fam", typeof(EnumFamily), Model.Family)%> 

Pero esto no es así:

<%= Html.DropDownList("family", typeof(EnumFamily), Model.Family)%> 

Debido a que estoy tratando de pasar todo el objeto directamente al método de controlador estoy publicando a, lo haría muy como tener la lista desplegable nombrada para la propiedad en el modelo. Cuando utilizo el nombre "correcto", el menú desplegable se publica correctamente, simplemente no puedo configurar el valor seleccionado.

No creo que esto es importante, pero estoy corriendo MVC 1 en Mono 2.6

edición: Acabo de probar esto en Windows, y yo estoy viendo el mismo comportamiento

+0

Vi el mismo comportamiento, y funcioné al usar diferentes listas desplegables nombradas. – Nate

Respuesta

14

Trate de no usar el valor int para la enumeración/en lugar de:

item.Value = value.ToString();

uso:

item.Value = Enum.GetName(type, value);

imo lo que está sucediendo es que está configurando automáticamente el valor seleccionado del menú desplegable para que coincida con el modelo, utilizando el nombre enum en lugar de su valor int. Recuerde que el motor de vistas busca el valor ya seleccionado no solo en el formulario publicado (en los casos en que ya se está publicando) sino también en el modelo + viewdata que se pasa a la vista. Solo si no lo encuentra allí, usará el valor seleccionado que haya especificado.

+0

Esto parece ser solo el boleto Freddy, muchas gracias. Ojalá hubiera aumentado la recompensa. Realmente pensé que sería vinculante por el valor enum, pero es bueno saber finalmente qué está pasando. Ahora tengo que volver y deshacer todos los hacks que puse en su lugar, así que supongo que debería estar enojado contigo;) – AlexCuse

0

Esto no lo hace parece bastante correcto, pero encontré que si le pongo un nombre a la lista desplegable con {nameOfInputParameter}. {propertyName} carga AND posts correctamente. Por lo tanto, si el formulario en cuestión se anuncio a un método que tenga un parámetro del mismo tipo que el modelo de la forma llamada "myModel" en el menú desplegable de la familia puede ser configurado de esta manera:

<%= Html.DropDownList("myModel.family", typeof(EnumFamily), Model.Family)%> 

Esto hace que con un id de myModel_family y un nombre de myModel.family. No estoy seguro de cómo sentirme acerca de esto, me parece un poco desagradable. Pero parece estar funcionando hasta ahora. Sin embargo, introduce un nuevo problema. Ya no se puede inicializar cuadros de texto, etc ..., así:

<%= Html.TextBox("name") %> 

Esto cargará los valores correctamente, pero cuando se publicar en el método controlador de tomar "myModel" como parámetro los valores no son reconocidos como parte del objeto que se envía. Entonces, debemos incluir el nombre del parámetro en nuestro nombre de entrada.

Sin embargo, la siguiente no se resuelve en un valor, al menos utilizando el ligante modelo por defecto (Me pregunto si escarbar en que va a mantener la mejor respuesta a esta pregunta):

<%= Html.TextBox("myModel.name") %> 

Así que hay que hacer esto:

<%= Html.TextBox("myModel.name", Model.Name) %> 

todo esto es poniendo bastante bruto (especialmente en las páginas en las que necesito para ser capaz de hacer frente a situaciones en las que el modelo es nulo).Con suerte alguien tiene una idea mejor :)

4

En realidad, esta es la solución. La misma solución que la mía en esta pregunta.
ASP.NET MVC - Html.DropDownList - Value not set via ViewData.Model

public static string DropDownList(this HtmlHelper helper, string name, Type type, object selected) 
    { 
     if (!type.IsEnum) 
      throw new ArgumentException("Type is not an enum."); 

     if (selected != null && selected.GetType() != type) 
      throw new ArgumentException("Selected object is not " + type.ToString()); 

     var enums = new List<SelectListItem>(); 
     foreach (int value in Enum.GetValues(type)) 
     { 
      var item = new SelectListItem(); 
      item.Value = value.ToString(); 
      item.Text = Enum.GetName(type, value); 

      if (selected != null) 
       item.Selected = (int)selected == value; 

      enums.Add(item); 
     } 

     // set ViewData first 
     helper.ViewData[name] = enums; 

     // pass in "null" intentionally into the DropDownList extension method 
     return System.Web.Mvc.Html.SelectExtensions.DropDownList(helper, name, null, "--Select--"); 
    } 

Usando item.Value = Enum.GetName(type, value); hace que el menú desplegable < opción > valores que se representan como los nombres ENUM. Personalmente prefiero tener int valores como devolución de datos.

Espero que ayude.

+0

Interesante - No pensé en usar ViewData así. No estoy seguro de querer ir por esa ruta en este punto, pero realmente aprecio la respuesta. Me aseguraré de probar esto si tengo algún problema con el enfoque actual. – AlexCuse

+0

Esta fue una respuesta increíble, ¡gracias! – loraderon

+0

Esto es asombroso Estaba buscando una solución en todas partes – bman

Cuestiones relacionadas