user949286
user949286

Reputation: 1279

ListBoxFor MultiSelectList does not select values

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

Answers (1)

user3559349
user3559349

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

Related Questions