0

In the view, I have

<div class="form-group">
    <div>
        @Html.LabelFor(m => m.DoctorList, new { @class = "control-label" })
    </div>
    <div>
        @Html.ListBoxFor(m => m.DoctorList, new MultiSelectList((List<SelectListItem>)ViewBag.DoctorList, "Value", "Text", ((List<string>)(ViewBag.DoctorsSelected)).ToArray()), new {style="display:block;height:20.0em;", @class = "form-control", Multiple = "multiple"})

    </div>
</div>

DoctorList is a list in model, ViewBag.DoctorList is the entire list of doctors, they are something similar to:

public static List<SelectListItem> GetDoctorList()
{
    List<SelectListItem> ret = new List<SelectListItem>();

    // load doctors from database
    // for now, fake data
    for (int k = 1; k <= 30; k++)
    {
        string n = "Doctor" + k.ToString();
        ret.Add(new SelectListItem() { Value = n, Text = n });
    }
    return ret;
}

ViewBag.DoctorsSelected is a List, which is a list of doctor names, something similar to:

List<string> doctorsSelected = new List<string>();
doctorsSelected.Add("Doctor1");
doctorsSelected.Add("Doctor5");

What I want to do is that preselect the doctors in the listbox. However, it always shows the listbox, but no reselection.

I also tried to use below in GetDoctorList()

ret.Add(new SelectListItem() { Value = n, Text = n, Select = true });

Still no preselection.

Anyone knows how to do it? I'm using MVC4.

Thanks

1 Answer 1

2

You cannot use the same name for the property your binding to and the SelectList. Your model should have a property (say)

public IEnumerable<string> SelectedDoctors { get; set; }

and the view will be

@Html.ListBoxFor(m => m.SelectedDoctors, (IEnumerable<SelectListItem>)ViewBag.DoctorList)

If SelectedDoctors contains values that match the values in the SelectList, then those items will be selected when the view is rendered. For example in the controller,

model.SelectedDoctors = new List<string> { "Doctor1", "Doctor5" };
return View(model);

Note also that ViewBag.DoctorList is already IEnumerable<SelectListItem> so its just pointless extra overhead to create an identical new IEnumerable<SelectListItem> from it using new SelectList() in your view.

Edit (in response to OP query as to why the names must be different)

The way the ListBoxFor() works is

  1. Get the value of the property your binding to from the ViewDataDictionary (in your case the item in the ViewDataDictionary is List<SelectListItem>).
  2. Build a new IEnumerable<SelectListItem> from the SelectList provided in the second parameter (in order to set the Selected property of each SelectListItem based on the values your binding to).
  3. Generate the html for each <option> element based on the Value, Text and Selected properties of each SelectListItem.

In your case, as each SelectListItem is created, its checks if any values in the property your binding to match the Value property of the SelectList, but your values are "System.Web.Mvc.SelectListItem" (they are complex objects so the .ToString() value of the object is used) and none of your SelectListItems have a value of "System.Web.Mvc.SelectListItem" (just "Doctor1", "Doctor2" etc.) so the Selected property is false and consequently, none of the <option> elements have the selected="selected" attribute set.

The above is a simplified explanation and if your want to see how it all works, you can view/download the source code here.

Sign up to request clarification or add additional context in comments.

3 Comments

Well, you are right, "You cannot use the same name for the property your binding to and the SelectList". But why?
That will take about a page or 2 to explain in detail :) - but I see if I can add a simplified explanation later (need a break for an hour or 2)
See update for an explanation as to why having the same names do not work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.