net mvc llenar dropdownlist drop down asp asp.net-mvc asp.net-mvc-2

asp.net mvc - mvc - Desafíos con la selección de valores en ListBoxFor



dropdownlistfor asp net (3)

Trabajando en mi primera aplicación web ASP.Net MVC2 recientemente, me encontré con algunos problemas cuando necesitaba seleccionar múltiples valores en un cuadro de lista. Trabajé alrededor con jQuery, pero seguí y armé un código muy simple para demostrar. Estoy usando EF para el modelo, con dos entidades: Clientes y HelpDeskCalls:

Controlador:

public ActionResult Edit(int id) { Customer currCustomer = ctx.Customers.Include("HelpDeskCalls").Where(c => c.ID == id).FirstOrDefault(); List<HelpDeskCall> currCustCalls = (ctx.HelpDeskCalls.Where(h => h.CustomerID == id)).ToList(); List<SelectListItem> currSelectItems = new List<SelectListItem>(); List<String> selectedValues = new List<string>(); foreach (HelpDeskCall currCall in currCustCalls) { bool isSelected = (currCall.ID % 2 == 0) ? true : false; //Just select the IDs which are even numbers... currSelectItems.Add(new SelectListItem() { Selected = isSelected, Text = currCall.CallTitle, Value = currCall.ID.ToString() }); //add the selected values into a separate list as well... if (isSelected) { selectedValues.Add(currCall.ID.ToString()); } } ViewData["currCalls"] = (IEnumerable<SelectListItem>) currSelectItems; ViewData["currSelected"] = (IEnumerable<String>) selectedValues; return View("Edit", currCustomer); }

Ver:

<div class="editor-field"> <%: Html.ListBoxFor(model => model.HelpDeskCalls, new MultiSelectList(Model.HelpDeskCalls, "ID", "CallTitle", (IEnumerable) ViewData["currSelected"]), new { size = "12" })%> <%: Html.ListBoxFor(model => model.HelpDeskCalls, ViewData["currCalls"] as IEnumerable<SelectListItem>, new { size = "12"}) %> <%: Html.ListBox("Model.HelpDeskCalls", new MultiSelectList(Model.HelpDeskCalls, "ID", "CallTitle", (IEnumerable)ViewData["currSelected"]), new { size = "12"}) %> <%: Html.ValidationMessageFor(model => model.HelpDeskCalls) %> </div>

Para esta muestra, solo estoy seleccionando HelpDeskCall.IDs que son pares. Estoy probando dos sintaxis diferentes para ListBoxFor: One usa un IEnumerable de valores para las selecciones, uno que usa un IEnumerable de SelectListItems. De forma predeterminada, cuando ejecuto este código, no se realizan selecciones en ListBoxFor, pero el ListBox sin tipeo fuerte se selecciona correctamente.

Leí esta publicación en ASP.Net y este hilo en SO, pero no hay alegría. De hecho, si agrego Override ToString () a mi clase HelpDeskCall (como se sugiere en el hilo de ASP.net), se seleccionan todos los valores, lo que tampoco es correcto.

Si alguien pudiera arrojar algo de luz sobre cómo debería funcionar esto (y lo que me estoy perdiendo o haciendo mal), entonces este neófito estaría muy agradecido.


Aquí hay un ejemplo que ilustra la versión fuertemente tipada:

Modelo:

public class MyViewModel { public int[] SelectedItemIds { get; set; } public MultiSelectList Items { get; set; } }

Controlador:

public class HomeController : Controller { public ActionResult Index() { // Preselect items with id 1 and 3 var selectedItemIds = new[] { 1, 3 }; var model = new MyViewModel { Items = new MultiSelectList( new[] { // TODO: Fetch from your repository new { Id = 1, Name = "item 1" }, new { Id = 2, Name = "item 2" }, new { Id = 3, Name = "item 3" }, }, "Id", "Name", selectedItemIds ) }; return View(model); } }

Ver:

<%: Html.ListBoxFor(x => x.SelectedItemIds, Model.Items) %>


He encontrado una mejor solución. Forma usual de preseleccionar la lista de selección:

@Html.ListBoxFor( model => model.Roles, new MultiSelectList(db.Roles, "Id", "Name") ) @Html.ValidationMessageFor(model => model.Roles)

No funciona ..., nunca se selecciona ninguna opción, hasta que:

public ActionResult Edit(int id) { var user = db.Users.Find(id); // this is workaround for http://aspnet.codeplex.com/workitem/4932?ProjectName=aspnet ViewData["Roles"] = user.Roles.Select(r => r.Id); return View(user); }

Los Roles seleccionados deben almacenarse en ViewData, para solucionar errores desagradables.


No sé si este comportamiento ha cambiado en el RTM de MVC3 que estoy usando, pero parece que la selección y el enlace ahora funcionan de la caja. El único inconveniente es que el modelo debe contener una propiedad con los ID, así:

public class MyViewModel { public int[] ItemIDs { get; set; } }

Entonces, lo siguiente en la vista funcionaría bien, tanto preseleccionando los valores correctos como vinculando correctamente durante la publicación:

@Html.ListBoxFor(model => model.ItemIDs, (IEnumerable<SelectListItem>)(new[] { new SelectListItem() { Value = "1", Text = "1" }, new SelectListItem() { Value = "2", Text = "2" } }))