I'm developing an ASP.NET MVC 5 application, with C# and .NET Framework 4.6.1.
I have this View
:
@model MyProject.Web.API.Models.AggregationLevelConfViewModel
[...]
@Html.DropDownListFor(m => m.Configurations[0].HelperCodeType, (SelectList)Model.HelperCodeTypeItems, new { id = "Configurations[0].HelperCodeType" })
The ViewModel
is:
public class AggregationLevelConfViewModel
{
private readonly List<GenericIdNameType> codeTypes;
private readonly List<GenericIdNameType> helperCodeTypes;
public IEnumerable<SelectListItem> CodeTypeItems
{
get { return new SelectList(codeTypes, "Id", "Name"); }
}
public IEnumerable<SelectListItem> HelperCodeTypeItems
{
get { return new SelectList(helperCodeTypes, "Id", "Name"); }
}
public int ProductionOrderId { get; set; }
public string ProductionOrderName { get; set; }
public IList<Models.AggregationLevelConfiguration> Configurations { get; set; }
public AggregationLevelConfViewModel()
{
// Load CodeTypes to show it as a DropDownList
byte[] values = (byte[])Enum.GetValues(typeof(CodeTypes));
codeTypes = new List<GenericIdNameType>();
helperCodeTypes = new List<GenericIdNameType>();
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);
}
}
}
And Models.AggregationLevelConfiguration
is:
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; }
}
I need to set selected value in these properties:
public IEnumerable<SelectListItem> CodeTypeItems
{
get { return new SelectList(codeTypes, "Id", "Name"); }
}
public IEnumerable<SelectListItem> HelperCodeTypeItems
{
get { return new SelectList(helperCodeTypes, "Id", "Name"); }
}
But I can't set it in new SelectList(codeTypes, "Id", "Name");
or new SelectList(helperCodeTypes, "Id", "Name");
because the selected value are in Configurations
array: fields AggregationLevelConfiguration.CodeType
and AggregationLevelConfiguration.HelperCodeType
.
I think I have to set selected value in the View, but I don't know how to do it.
How can I set the selected values?
Unfortunately
@Html.DropDownListFor()
behaves a little differently than other helpers when rendering controls in a loop. This has been previously reported as an issue on CodePlex (not sure if its a bug or just a limitation)The are 2 option to solve this to ensure the correct option is selected based on the model property
Option 1 (using an
EditorTemplate
)Create a custom
EditorTemplate
for the type in the collection. Create a partial in/Views/Shared/EditorTemplates/AggregationLevelConfiguration.cshtml
(note the name must match the name of the typeand then in the main view, pass the
SelectList
to theEditorTemplate
asadditionalViewData
Option 2 (generate a new
SelectList
in each iteration and set theselectedValue
)In this option your property
CodeTypeItems
should to beIEnumerable<GenericIdNameType>
, not aSelectList
(or just makecodeTypes
a public property). Then in the main viewSide note: there is no need to use
new { id = "Configurations[0].HelperCodeType"
- theDropDownListFor()
method already generated thatid
attributeI wrote this class to overcome an issue I was having with selecting an option in an html select list. I hope it helps someone.
And
And to use it:
I leave this in case it helps someone else. I had a very similar problem and none of the answers helped.
We had in a view this line at the top:
and then below in the view:
We had a property in my ViewData with the same name as the selector for the lambda expression and for some reason that makes the dropdown to be rendered without any option selected.
We changed the name in ViewData to
ViewData["ExitFromTrustDeed2"]
and that made it work as expected.Weird though.