简体   繁体   中英

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?

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM