问题
I have the below code in a view. (index.cshtml)
Binding Problem
- The first drop down selects the correct value, based on the 'ChildItem' editor template.
- The second example using an inline drop down list does not work I don't want to create an editor template just to display drop down values.
- The odd thing is that TextBoxFor will show the correct value. This seems to be an issue just with the drop down list.
How do I fix the binding so that the second drop down works? I debugged it. It would appear that ViewData.Eval is not picking up the correct value from _.Children[i].ChooseId
.
Update (bug)
This is a confirmed bug (low priority, how?) in the MVC framework http://aspnet.codeplex.com/workitem/8311
@using (Html.BeginForm())
{
for (int i = 0; i < Model.Children.Count(); i++)
{
<p>A: @Html.EditorFor(_ => _.Children[i], "ChildItem")</p>
<p>B: @Html.DropDownListFor(_ => _.Children[i].ChooseId, TestModel.PeopleSelect)</p>
}
<button type="submit">GO</button>
}
I have tried using DropDownListFor(_ => Model.Children[i].ChooseId)
, same result.
using TextBoxFor(_ => _.Children[i].ChooseId)
shows the correct value, wierd?
For reference here is ChildItem.cshtml
@using dropdown.Controllers
@using dropdown.Models
@model dropdown.Models.TestPerson
@Html.DropDownListFor(_ => _.ChooseId, TestModel.PeopleSelect)
It looks like this:
回答1:
I have subsequently found this: http://aspnet.codeplex.com/workitem/8311 It's a confirmed bug.
The only workaround i have found is this.
Mark Selected Item
@Html.DropDownListFor(_ => _.Children[i].ChooseId, Mark(TestModel.PeopleSelect, Model.Children[i].ChooseId))
Mark Function / Extension Method
@functions {
private IEnumerable<SelectListItem> Mark(IEnumerable<SelectListItem> items, object Id)
{
foreach (var item in items)
if (string.CompareOrdinal(item.Value, Convert.ToString(Id)) == 0)
item.Selected = true;
return items;
}
}
回答2:
You could put the items into a partial view and load that for your child objects, OR...
You could opt to do a foreach
loop on the child collection, and use it like this:
foreach (var itm in Model.Children)
{
@Html.DropDownListFor(modelItem => itm.ChooseId,
new SelectList( (IEnumerable<SelectListItem>)TestModel.PeopleSelect, "Value", "Text", itm.ChooseId),
htmlAttributes: new { @class = "form-control" }
)
}
This assumes that TestModel.PeopleSelect
has been created as a SelectListItem[]
or IEnumerable<SelectListItem>
. Code to do that properly is in my answer on a related question: ASP.NET MVC4 Model's Child Collection Drop Down List not binding properly
Doing a for
loop on the child collection gave me the error:
Cannot apply indexing with [] to an expression of type 'ICollection<Children>'
So I wouldn't recommend that.
来源:https://stackoverflow.com/questions/14951544/mvc4-binding-drop-down-list-in-a-list-bug