Reputation: 1279
I'm incredibly confused, because this seems like it should be simple but I can't get my ListBox
to be populated with selected values. I've looked at several other answers and I can't figure out what I'm doing wrong.
This is my model:
public class ItemViewModel
{
public IEnumerable<Item> AllItems { get; set; }
public IEnumerable<Item> SelectedItems { get; set; }
}
public class Item
{
public string Id { get; set; }
public string Name { get; set; }
}
This is my controller action:
public ActionResult ListBoxTest()
{
var viewModel = new ItemViewModel()
{
AllItems = new List<Item>()
{
new Item()
{
Id = "1",
Name = "Name1"
},
new Item()
{
Id = "2",
Name = "Name2"
}
},
SelectedItems = new List<Item>()
{
new Item()
{
Id = "1",
Name = "Name1"
}
}
};
return this.View(viewModel);
}
And this is the line in my view (using a default MVC View template):
@Html.ListBoxFor(m => m.SelectedItems, new MultiSelectList(Model.AllItems, "Id", "Name", Model.SelectedItems.Select(s => s.Id)), new { multiple = "multiple"})
I've also tried omitting the selected values:
@Html.ListBoxFor(m => m.SelectedItems, new MultiSelectList(Model.AllItems, "Id", "Name"), new { multiple = "multiple"})
And making the selected values a list:
@Html.ListBoxFor(m => m.SelectedItems, new MultiSelectList(Model.AllItems, "Id", "Name", Model.SelectedItems.Select(s => s.Id).ToList()), new { multiple = "multiple"})
But no matter what I do, the list items are never selected. What am I doing wrong?
Upvotes: 4
Views: 14357
Reputation:
You cannot bind a <select>
element to a collection of complex objects. A multiple select only posts back an array of simple values - the values of the selected options.
Your model needs to be
public class ItemViewModel
{
public IEnumerable<Item> AllItems { get; set; }
public IEnumerable<int> SelectedItems { get; set; }
}
and in the controller
SelectedItems = new List<int>(){ 1 }
then using
@Html.ListBoxFor(m => m.SelectedItems, new SelectList(Model.AllItems, "Id", "Name")
will select the first option in the dropdownlist.
Note that the ListBoxFor()
method sets multiple="multiple"
so there is no need to set it again. In addition, Setting the last parameter of in the SelectList()
(or MultiSelectList()
) constructor is pointless. Its the value of the property your binding to which determines what is selected and internally the ListBoxFor()
method ignores that parameter.
I would also suggest your property should be
public IEnumerable<SelectListItem> AllItems { get; set; }
so that you can simply use
@Html.ListBoxFor(m => m.SelectedItems, Model.AllItems)
Upvotes: 7