asp.net-mvc - studio - mvc asp.net c#
DropDownListFor en EditorTemplate no selecciona valor (12)
Tengo una plantilla de editor para un objeto personalizado. Dentro de esa plantilla de editor utilizo un par de DropDownListFor helpers. En cada uno de ellos especifico una propiedad de modelo única (con el valor preseleccionado) y la lista de selección que contiene todas las opciones de selección.
Ejemplo:
<%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>
Sé que los valores de las opciones se están rellenando (desde la fuente de visualización) y que mi modelo se transfiere con el valor de ID correcto (DocumentCategoryType).
Cuando se representa la vista, no hay ningún elemento seleccionado en mi menú desplegable y, por lo tanto, se establece de manera predeterminada en el primer valor (no seleccionado).
¿Alguien tiene alguna idea?
Gracias.
Aquí hay otra buena solución si la fuente de su lista desplegable es un IEnumerable en lugar de una SelectList:
public static SelectList MakeSelection(this IEnumerable<SelectListItem> list, object selection, string dataValueField = "Value", string dataTextField = "Text")
{
return new SelectList(list, dataValueField, dataTextField, selection);
}
Asegúrese de tener un valor asignado a m.DocumentCategoryType cuando lo envíe a la vista.
En general, este valor se restablecerá cuando haga una publicación posterior, de modo que solo necesita especificar el valor cuando regrese a su vista.
Al crear una lista desplegable, debe pasarle dos valores. 1. Aquí es donde almacenará el valor seleccionado 2. ¿Es la Lista real?
Ejemplo
<%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>
Cometí el error de establecer el elemento de la lista de selección Valor seleccionado en Verdadero. Esto no hará nada. En su lugar, simplemente asigne un valor a m.DocumentCategoryType en su controlador y esto realmente hará la selección por usted.
Copiado na pegado de mi proyecto:
<%= Html.DropDownListFor(m => m.Profession.Profession_id, new SelectList(Model.Professions, "Profession_id", "Profession_title"),"-- Profession --")%>
Modelo que se pasa:
...
public Profession Profession { get; set; }
public IList<Profession> Professions { get; set; }
...
Html generado:
<select id="Profession_Profession_id" name="Profession.Profession_id">
<option value="">-- Profesion --</option>
<option value="4">Informatico</option>
<option selected="selected" value="5">Administracion</option>
</select>
Funciona para mi. Tengo esto en el formulario y la única desventaja es que si el modelo no es válido y devuelvo el modelo a la vista, tengo que volver a cargar la lista de profesiones.
obj.Professions = ProfileService.GetProfessions();
return View(obj);
Estaba preocupado por la realización de hacer tantas copias de mi lista de selección, así que en su lugar, agregué el valor seleccionado como un atributo personalizado, luego usé jquery para realizar la selección del elemento:
@Html.DropDownListFor(item => item.AttendeeID, attendeeChoices, String.Empty, new { setselectedvalue = Model.AttendeeID })
........
jQuery("select[setselectedvalue]").each(function () { e = jQuery(this); e.val(e.attr("setselectedvalue")); });
Logré resolver el mismo problema diciendo lo siguiente:
new SelectList(sections.Select(s => new { Text = s.SectionName, Value = s.SectionID.ToString() }), "Value", "Text")
Este truco consiste en convertir el valor en una cadena. Sé que esto ha sido mencionado en respuestas anteriores, pero mi solución me parece un poco más limpia :). Espero que esto ayude.
Mirar a través del código fuente de ASP.NET MVC 2 revela algunas soluciones a este problema. Esencialmente, cualquier SelectListItem
en SelectList
pasado en el método de extensión auxiliar que tiene la propiedad Selected
establecida en true no tiene ninguna influencia sobre el elemento <option>
representado con el atributo selected
aplicado para el elemento.
El atributo selected
en los elementos <option>
está determinado por
1) verificar que el método de extensión auxiliar fue pasado a SelectList
. Si esto es nulo, el marco buscará en ViewData un valor correspondiente a la clave que es la propiedad del modelo de vista para la que desea representar la lista desplegable. Si el valor es una lista de SelectList
, se usará para hacer que la <select>
incluya tomar cualquier valor seleccionado, siempre que el estado del modelo para la propiedad del modelo sea nulo.
2) Si se ha pasado una SelectList
en el método de extensión auxiliar y el estado del modelo para la propiedad del modelo es nulo, la estructura buscará en el ViewData un valor predeterminado, utilizando el nombre de la propiedad del modelo como la clave. El valor en los datos de vista se convierte en una cadena y cualquier elemento en la lista de SelectList
transfiera al método de extensión auxiliar que tenga un valor (si no se establece ningún valor, se marcará el texto) que coincida con el valor predeterminado tendrá la propiedad Selected
se establece en verdadero, que a su vez representará una <option>
con el atributo selected="selected"
.
Al unir esto, hay dos opciones plausibles que puedo ver para tener una opción seleccionada y usar DropDownListFor
fuertemente tipado:
Usando el siguiente modelo de vista
public class CategoriesViewModel
{
public string SelectedCategory { get; private set ; }
public ICollection<string> Categories { get; private set; }
public CategoriesViewModel(string selectedCategory, ICollection<string> categories)
{
SelectedCategory = selectedCategory;
Categories = categories;
}
}
Opción 1
Establezca un valor en ViewData en el controlador que represente su vista con el nombre de propiedad de la colección utilizada para representar el menú desplegable
la acción del controlador
public class CategoriesController
{
[HttpGet]
public ViewResult Select()
{
/* some code that gets data from a datasource to populate the view model */
ICollection<string> categories = repository.getCategoriesForUser();
string selectedCategory = repository.getUsersSelectedCategory();
CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories);
this.ViewData["Categories"] = selectedCategory;
return View(model);
}
[HttpPost]
public ActionResult Select(CategoriesViewModel model)
{
/* some code that does something */
}
}
y en la vista fuertemente tipada
<%: Html.DropDownListFor(m => m.Categories, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %>
opcion 2
Renderice el menú desplegable usando el nombre de la propiedad de los elementos seleccionados
la acción del controlador
public class CategoriesController
{
[HttpGet]
public ViewResult Select()
{
/* some code that gets data from a datasource to populate the view model */
ICollection<string> categories = repository.getCategoriesForUser();
string selectedCategory = repository.getUsersSelectedCategory();
CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories);
return View(model);
}
[HttpPost]
public ActionResult Select(CategoriesViewModel model)
{
/* some code that does something */
}
}
y en la vista fuertemente tipada
<%: Html.DropDownListFor(m => m.SelectedCategory, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %>
Se confirma como un error @ aspnet.codeplex.com y solo se comporta así para vistas fuertemente tipadas.
Solución alternativa: llene su lista de selección en el código de vista
me gusta
<%= Html.DropDown("DocumentCategoryType", new SelectList(Model.Categories,"id","Name",Model.SelectedCategory")) =>
También SelectList
la solución completando una nueva lista de SelectList
que tiene seleccionado el elemento SelectListItem
, pero creamos este método de extensión para mantener la llamada a DropDownListFor
un poco más limpio:
public static SelectList MakeSelection(this SelectList list, object selection)
{
return new SelectList(list.Items, list.DataValueField, list.DataTextField, selection);
}
Entonces su llamada DropDownListFor
convierte en:
<%= Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList.MakeSelection(Model.DocumentCategoryType)) %>
También tuve este problema con un campo ProgramName. Resulta que utilizamos ViewBag.ProgramName en BaseController y Layout.cshtml, y esto fue para un propósito diferente. Dado que el valor en ViewBag.ProgramName no se encontró en la lista desplegable, no se seleccionó ningún valor aunque SelectListItem.Selected era verdadero para un elemento de la lista. Acabamos de cambiar el ViewBag para usar una clave diferente y el problema se resolvió.
Yuck. Terminé resolviéndolo así. Espero que esto se arregle para RTM.
<%if(Model!=null){ %>
<%= Html.DropDownListFor(m => m.DocumentCategoryType, new SelectList(Model.DocumentCategoryTypeList,"Value","Text", Model.DocumentCategoryType))%>
<%}else{%>
<%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>
<%}%>
Aquí hay un drop-in DropDownListFor reemplazo que varía solo ligeramente de la fuente MVC original.
Ejemplo:
<%=Html.FixedDropDownListFor(m => m.DocumentCategoryType,
Model.DocumentCategoryTypeList) %>
Model.DocumentCategoryTypeList
Este es probablemente tu problema. En SelectListItems, ¿establece el valor para el resultado .ToString ()?
var list = new List<SelectListItem>()
{
new SelectListItem()
{
Value = Category.Book.ToString(),
Text = "Book"
},
new SelectListItem()
{
Value = Category.BitsAndPieces.ToString(),
Text = "Bits And Pieces" },
new SelectListItem()
{
Value = Category.Envelope.ToString(),
Text = "Envelopes" }
};
Funciona para mí después de hacer eso. Solo necesita poder hacer coincidir el valor del objeto