MVC5 Razor html.dropdownlist para el conjunto seleccionado cuando el valor está en matriz

Estoy desarrollando una aplicación ASP.NET MVC 5, con C # y .NET Framework 4.6.1.

Tengo esta View :

 @model MyProject.Web.API.Models.AggregationLevelConfViewModel [...] @Html.DropDownListFor(m => m.Configurations[0].HelperCodeType, (SelectList)Model.HelperCodeTypeItems, new { id = "Configurations[0].HelperCodeType" }) 

El ViewModel es:

 public class AggregationLevelConfViewModel { private readonly List codeTypes; private readonly List helperCodeTypes; public IEnumerable CodeTypeItems { get { return new SelectList(codeTypes, "Id", "Name"); } } public IEnumerable HelperCodeTypeItems { get { return new SelectList(helperCodeTypes, "Id", "Name"); } } public int ProductionOrderId { get; set; } public string ProductionOrderName { get; set; } public IList Configurations { get; set; } public AggregationLevelConfViewModel() { // Load CodeTypes to show it as a DropDownList byte[] values = (byte[])Enum.GetValues(typeof(CodeTypes)); codeTypes = new List(); helperCodeTypes = new List(); for (int i = 0; i < values.Length; i++) { GenericIdNameType cType = new GenericIdNameType() { Id = values[i].ToString(), Name = EnumHelper.GetDescription((CodeTypes)values[i]) }; if (((CodeTypes)values[i]) != CodeTypes.NotUsed) codeTypes.Add(cType); helperCodeTypes.Add(cType); } } } 

Y Models.AggregationLevelConfiguration es:

 public class AggregationLevelConfiguration { public byte AggregationLevelConfigurationId { get; set; } public int ProductionOrderId { get; set; } public string Name { get; set; } public byte CodeType { get; set; } public byte HelperCodeType { get; set; } public int PkgRatio { get; set; } public int RemainingCodes { get; set; } } 

Necesito establecer el valor seleccionado en estas propiedades:

 public IEnumerable CodeTypeItems { get { return new SelectList(codeTypes, "Id", "Name"); } } public IEnumerable HelperCodeTypeItems { get { return new SelectList(helperCodeTypes, "Id", "Name"); } } 

Pero no puedo configurarlo en la new SelectList(codeTypes, "Id", "Name"); o new SelectList(helperCodeTypes, "Id", "Name"); porque el valor seleccionado se encuentra en la matriz Configurations : campos AggregationLevelConfiguration.CodeType y AggregationLevelConfiguration.HelperCodeType .

Creo que tengo que establecer el valor seleccionado en la Vista, pero no sé cómo hacerlo.

¿Cómo puedo configurar los valores seleccionados?

Lamentablemente, @Html.DropDownListFor() comporta de forma un poco diferente que otros helpers al procesar controles en un bucle. Esto se informó anteriormente como un problema en CodePlex (no estoy seguro de si es un error o simplemente una limitación)

La opción 2 es resolver esto para garantizar que se selecciona la opción correcta en función de la propiedad del modelo

Opción 1 (usando una EditorTemplate )

Cree un EditorTemplate personalizado para el tipo en la colección. Cree un parcial en /Views/Shared/EditorTemplates/AggregationLevelConfiguration.cshtml (tenga en cuenta que el nombre debe coincidir con el nombre del tipo

 @model yourAssembly.AggregationLevelConfiguration @Html.DropDownListFor(m => m.HelperCodeType, (SelectList)ViewData["CodeTypeItems"]) .... // other properties of AggregationLevelConfiguration 

y luego en la vista principal, pase la SelectList de SelectList a la EditorTemplate del EditorTemplate como additionalViewData

 @using (Html.BeginForm()) { ... @Html.EditorFor(m => m.Configurations , new { CodeTypeItems = Model.CodeTypeItems }) ... 

Opción 2 (generar una nueva SelectList de SelectList en cada iteración y establecer el valor selectedValue )

En esta opción, su propiedad CodeTypeItems debe ser IEnumerable , no SelectList (o simplemente hacer codeTypes una propiedad pública). Luego en la vista principal

 @Html.DropDownListFor(m => m.Configurations[0].HelperCodeType, new SelectList(Model.CodeTypeItems, "Id", "Name", Model.Configurations[0].HelperCodeType) 

Nota al new { id = "Configurations[0].HelperCodeType" : no es necesario utilizar new { id = "Configurations[0].HelperCodeType" – el método DropDownListFor() ya generó ese atributo de id

Escribí esta clase para superar un problema que tenía al seleccionar una opción en una lista de selección html. Espero que esto ayude a alguien.

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web; namespace Login_page.Models { public class HTMLSelect { public string id { get; set; } public IEnumerable @class { get; set; } public string name { get; set; } public Boolean required { get; set; } public string size { get; set; } public IEnumerable SelectOptions { get; set; } public HTMLSelect(IEnumerable options) { } public HTMLSelect(string id, string name) { this.id = id; this.name = name; } public HTMLSelect(string id, string name, bool required, IEnumerable options) { this.id = id; this.name = name; this.required = required; } private string BuildOpeningTag() { StringBuilder text = new StringBuilder(); text.Append(""); return text.ToString(); } public string GenerateSelect(IEnumerable options) { StringBuilder selectElement = new StringBuilder(); selectElement.Append(this.BuildOpeningTag()); foreach (SelectOption option in options) { StringBuilder text = new StringBuilder(); text.Append("\t"); text.Append(""); selectElement.Append(text.ToString()); } selectElement.Append(" 

Y

 public IEnumerable getOrderTypes() { List orderTypes = new List(); if (this.orderType == "OptionText") { orderTypes.Add(new SelectOption() { Value = "1", Text = "OptionText", Selected = true }); } else { orderTypes.Add(new SelectOption() { Value = "2", Text = "OptionText2" }); } } 

Y para usarlo:

 @{ Login_page.Models.HTMLSelect selectElement = new Login_page.Models.HTMLSelect("order-types", "order-types"); } @Html.Raw(selectElement.GenerateSelect(Model.getOrderTypes()));