¿Cómo puedo hacer para que funcione ASP.NET MVC SelectList?

Creo una lista de selección en mi controlador, para mostrar en la vista.

Intento crearlo sobre la marcha, algo así … así …

myViewData.PageOptionsDropDown = new SelectList(new [] {"10", "15", "25", "50", "100", "1000"}, "15"); 

Se comstack, pero el resultado es malo …

  10 15 25 50 100 1000  

Observe cómo no se selecciona ningún elemento?

¿¿Cómo puedo arreglar esto??

Así es como lo hago

 IList customers = repository.GetAll(); IEnumerable selectList = from c in customers select new SelectListItem { Selected = (c.CustomerID == invoice.CustomerID), Text = c.Name, Value = c.CustomerID.ToString() }; 

A segunda vista, no estoy seguro de saber qué es lo que buscas …

Yo uso un método de extensión:

uso

 var departmentItems = departments.ToSelectList(d => d.Code + " - " + d.Description, d => d.Id.ToString(), " - "); var functionItems = customerFunctions.ToSelectList(f => f.Description, f => f.Id.ToString(), " - "); 

con

 public static class MCVExtentions { public static List ToSelectList( this IEnumerable enumerable, Func text, Func value, string defaultOption) { var items = enumerable.Select(f => new SelectListItem() { Text = text(f), Value = value(f) }).ToList(); items.Insert(0, new SelectListItem() { Text = defaultOption, Value = "-1" }); return items; } } 

Usar el constructor que acepta items, dataValueField, dataTextField, selectedValue como parámetros:

 ViewData["myList"] = new SelectList(new[] { "10", "15", "25", "50", "100", "1000" } .Select(x => new {value = x, text = x}), "value", "text", "15"); 

Entonces en tu opinión:

 <%=Html.DropDownList("myList") %> 

ToSelectList la respuesta de Thomas Stock, creé estos métodos sobrecargados ToSelectList :

 using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; public static partial class Helpers { public static IEnumerable ToSelectList(this IEnumerable enumerable, Func value, bool selectAll = false) { return enumerable.ToSelectList(value, value, selectAll); } public static IEnumerable ToSelectList(this IEnumerable enumerable, Func value, object selectedValue) { return enumerable.ToSelectList(value, value, new List() { selectedValue }); } public static IEnumerable ToSelectList(this IEnumerable enumerable, Func value, IEnumerable selectedValues) { return enumerable.ToSelectList(value, value, selectedValues); } public static IEnumerable ToSelectList(this IEnumerable enumerable, Func value, Func text, bool selectAll = false) { foreach (var f in enumerable.Where(x => x != null)) { yield return new SelectListItem() { Value = value(f).ToString(), Text = text(f).ToString(), Selected = selectAll }; } } public static IEnumerable ToSelectList(this IEnumerable enumerable, Func value, Func text, object selectedValue) { return enumerable.ToSelectList(value, text, new List() { selectedValue }); } public static IEnumerable ToSelectList(this IEnumerable enumerable, Func value, Func text, IEnumerable selectedValues) { var sel = selectedValues != null ? selectedValues.Where(x => x != null).ToList().ConvertAll(x => x.ToString()) : new List(); foreach (var f in enumerable.Where(x => x != null)) { yield return new SelectListItem() { Value = value(f).ToString(), Text = text(f).ToString(), Selected = sel.Contains(value(f).ToString()) }; } } } 

En su controlador, puede hacer lo siguiente:

 var pageOptions = new[] { "10", "15", "25", "50", "100", "1000" }; ViewBag.PageOptions = pageOptions.ToSelectList(o => o, "15" /*selectedValue*/); 

Y finalmente en tu Vista, pon:

 @Html.DropDownList("PageOptionsDropDown", ViewBag.PageOptions as IEnumerable, "(Select one)") 

Dará como resultado el resultado deseado; por supuesto, puede omitir la opción "(Select one)" etiqueta arriba si no desea el primer elemento vacío:

  

Actualización: una lista de códigos revisada se puede encontrar aquí con comentarios XML.

El problema es que SelectList funciona según lo diseñado. El error está en el diseño. Puede establecer la Propiedad seleccionada en SelectedItem, pero esto se ignorará por completo, si recorre la lista con GetEnumerator () (o si Mvc hace eso por usted). Mvc creará nuevos SelectListItems en su lugar.

Debe usar el SelectList ctor con SelectListItem [], el Text-Name, el Value-Name y el SelectedValue. ¡Tenga en cuenta que debe pasar como SelectedValue el VALOR de SelectListItem, que desea seleccionar, no el SelectListItem en sí mismo! Ejemplo:

 SelectList sl = new SelectList( new[]{ new SelectListItem{ Text="one", Value="1"}, new SelectListItem{ Text="two", Value="2"}, new SelectListItem{ Text="three", Value="3"} }, "Text", "Value", "2" ); 

(No probado esto, pero tuve el mismo problema)

luego la segunda opción obtendrá el atributo = seleccionado “seleccionado”. Eso parece buenos viejos DataSets 😉

Esta es una opción:

 myViewData.PageOptionsDropDown = new[] { new SelectListItem { Text = "10", Value = "10" }, new SelectListItem { Text = "15", Value = "15", Selected = true } new SelectListItem { Text = "25", Value = "25" }, new SelectListItem { Text = "50", Value = "50" }, new SelectListItem { Text = "100", Value = "100" }, new SelectListItem { Text = "1000", Value = "1000" }, } 

Si eso es, literalmente, todo lo que quiere hacer, simplemente declarar la matriz como cadena corrige el problema del elemento seleccionado:

 myViewData.PageOptionsDropDown = new SelectList(new string[] {"10", "15", "25", "50", "100", "1000"}, "15"); 

Es muy sencillo hacer que SelectList y SelectedValue funcionen juntos, incluso si su propiedad no es un objeto simple como Int, String o Double.

Ejemplo:

Suponiendo que nuestro objeto Región es algo como esto:

 public class Region { public Guid ID { get; set; } public Guid Name { get; set; } } 

Y su modelo de vista es algo así como:

 public class ContactViewModel { public DateTime Date { get; set; } public Region Region { get; set; } public List Regions { get; set; } } 

Puedes tener el código a continuación:

 @Html.DropDownListFor(x => x.Region, new SelectList(Model.Regions, "ID", "Name")) 

Solo si reemplaza el método ToString del objeto Region por algo como:

 public class Region { public Guid ID { get; set; } public Guid Name { get; set; } public override string ToString() { return ID.ToString(); } } 

Esto tiene 100% de garantía para trabajar.

Pero realmente creo que la mejor manera de hacer que SelectList funcione al 100% en todos los circuitos es mediante el método Equals para probar el valor de la propiedad DropDownList o ListBox en cada elemento de la colección de elementos.

Parece que si tiene una vista fuertemente tipada, necesita cambiar la ID del menú desplegable para que NO sea el nombre de una propiedad en la clase heredada. Luego debe poner algo de lógica en su método de edición (POST) para extraer el valor seleccionado de FORMCollection y ponerlo en su instancia antes de confirmar sus cambios.

Esto es ciertamente un poco extraño, pero lo intenté y funciona.

Entonces, si su clase tiene un campo llamado CountryId, y muestra una lista de nombres de países, haga que el menú desplegable tenga una identificación de CountryName en lugar de CountryId, luego en la publicación, puede hacer algo con Collection [“CountryName”] .

Tuve exactamente el mismo problema. La solución es simple. Simplemente cambie el parámetro “nombre” pasado al asistente de DropDownList por algo que no coincida con ninguna de las propiedades existentes en su ViewModel. lea más aquí: http://www.dotnetguy.co.uk/post/2009/06/25/net-mvc-selectlists-selected-value-does-not-get-set-in-the-view

Cito al Dan Watson:

En MVC si la vista está fuertemente tipada, la opción seleccionada de la lista de selección será anulada y la propiedad de la opción seleccionada establecida en el constructor nunca alcanzará la vista y la primera opción del menú desplegable será seleccionada en su lugar (¿por qué todavía es un misterio?) .

¡aclamaciones!

Todas estas respuestas se ven muy bien, pero parece ser que el controlador está preparando datos para una Vista en un formato estructurado conocido, permitiendo que la vista simplemente itere un IEnumerable <> entregado a través del modelo y construya una lista de selección estándar y luego deje DefaultModelBinder devuelva el artículo seleccionado mediante un parámetro de acción. Sí, no, ¿por qué no? Separación de preocupaciones, ¿sí? Parece extraño tener el controlador para construir algo para que la interfaz de usuario y la vista sean específicos.

Sencillo:

 string[] someName = new string[] {"10", "15", "25", "50", "100", "1000"}; myViewData.PageOptionsDropDown = new SelectList(someName, "15"); 

Usando tu ejemplo, esto funcionó para mí:

controlador:

 ViewData["PageOptionsDropDown"] = new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }, "15"); 

ver:

 <%= Html.DropDownList("PageOptionsDropDown")%> 

Simplemente lo ejecuté así y no tuve problemas,

 public class myViewDataObj { public SelectList PageOptionsDropDown { get; set; } } public ActionResult About() { myViewDataObj myViewData = new myViewDataObj(); myViewData.PageOptionsDropDown = new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }, "15"); ViewData["myList"] = myViewData.PageOptionsDropDown; return View(); } 

y

 <%=Html.DropDownList("myList") %> 

también funcionó si haces esto,

 public ActionResult About() { myViewDataObj myViewData = new myViewDataObj(); myViewData.PageOptionsDropDown = new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }); ViewData["myListValues"] = myViewData.PageOptionsDropDown; ViewData["myList"] = "15"; return View(); } 

y

 <%=Html.DropDownList("myList",(IEnumerable)ViewData["myListValues"]) %> 
 MonthRepository monthRepository = new MonthRepository(); IQueryable entities = monthRepository.GetAllMonth(); List monthEntities = new List(); foreach(var r in entities) { monthEntities.Add(r); } ViewData["Month"] = new SelectList(monthEntities, "MonthID", "Month", "Mars"); 

Lo hago así:

 List list = new List{ new SelectListItem {Selected = true, Text = "Select", Value = "0"}, new SelectListItem {Selected = true, Text = "1", Value = "1"}, new SelectListItem {Selected = true, Text = "2", Value = "2"} }; return list.ToArray(); 

The ToArray () se ocupa de los problemas.

Si desea pasar texto aleatorio a su DropDownList, por ejemplo –Seleccione– puede hacerlo fácilmente con este código:

 @Html.DropDownListFor(x => x.CategoryId, new SelectList(Model.Categories, "Id", "Name"), "--Select--", new { @class = "form-control" }) 

Puede ser que tenga alguna ambigüedad en su ViewData:

Eche un vistazo aquí

el valor seleccionado en el modelo toma ventaja en lugar del elemento predeterminado. (Acepto que no leí todas las publicaciones)

No recuerdo cómo se configuró mvc 1, pero parece que quería que la lista de selección tuviera el mismo nombre que el campo al que pertenecía también …

Lo que encontré, como alguien dijo anteriormente, es que mis listas de selección no funcionaban en mvc2 cuando ViewData se enviaron, ya que se llamaba igual que el campo.

Por ejemplo:

<%= Html.DropDownListFor((model => model.ForID), (SelectList)ViewData["ForName"]) %>

funciona cuando

<%= Html.DropDownListFor((model => model.ForID), (SelectList)ViewData["ForID"]) %>

no funciona, ya que el nombre ViewData “ForID” tiene el mismo nombre que el campo para el que está trabajando

Una posible explicación es que el valor de la lista de selección a la que se está vinculando no es una cadena.

Entonces, en ese ejemplo, ¿el parámetro ‘PageOptionsDropDown’ es una cadena en su modelo? Porque si no es así, el valor seleccionado en la lista no se mostraría.

Si busca en el código fuente de MVC 2 en el método de extensión Html.DropDownList, nunca verifica la propiedad SelectedValue de la clase SelectList. Solo intentará hacer coincidir su Modelo.

Todas las anteriores son todas variaciones sobre un tema, es decir, cómo se envían muchos datos a la vista para una lista desplegable y todos son tan buenos como los demás (más o menos).

El problema está en la vista. Cree su propio método de extensión DropDownList que respete el valor de selección que establezca o repita a mano. Lo que mejor funciona para usted.

Si tiene una colección en su modelo y su vista está fuertemente tipeada, alguna variación de esto funcionará:

 @Html.DropDownListFor(x => x.RegionID, new SelectList(Model.Regions,"RegionID", "RegionName", Model.RegionID)) 

-o-

 @Html.DropDownList("RegionID", new SelectList(Model.Regions, "RegionID", "RegionName", Model.RegionID))