ASP.NET MVC2: DropDownListFor doesn't work properly with multiple selection + modelbinder
I am trying to figure out how this DropDownListFor works but with no success.
My controller creates a list of SelectListItems where I put all the groups found in the database:viewModel.Groups = Loa开发者_如何学JAVAdGroups(viewModel.User.AssociatedGroups);
this it the method:
private IList<SelectListItem> LoadGroups(List<String> associatedGroups)
{
var groups = _SecurityService
.LoadGroups()
.Select(e => new SelectListItem
{
Selected = associatedGroups.Contains<System.String>(e.Id.ToString()),
Value = e.Id.ToString(),
Text = e.Name
}).ToList();
return (groups);
}
As you can see I set the Selected element if there are associated groups in the list. I put this list in a field (Groups) of my custom viewmodel:
public class UsersViewModel
{
public UsersViewModel()
{
this.Groups = new List<SelectListItem>();
}
public Models.User User { get; set; }
public IList<SelectListItem> Groups { get; set; }
}
and send UsersViewModel to the view. I use this code to build a dropdown with multi-selection:
<%=Html.DropDownListFor(m => m.User.AssociatedGroups, (List<System.Web.Mvc.SelectListItem>)Model.Groups, new { @class = "dropDownGroups", multiple = "multiple" })%>
AssociatedGroups is a field the class Users (which is a member of my viewmodel):
public List<String> AssociatedGroups { get; set; }
There's nothing peculiar here. If I use this code I can I can't see the elements of the dropdown selected (and they have the attribute set, I've double checked), but I can bind the selections with AssociatedGroups when I post the form. If I change AssociatedGroups (field of the User class) with a string:
public String AssociatedGroups { get; set; }
I have the opposite behaviour:
I can see the elements of the dropdown checked but when I post the form there's no binding, or better, only one element is bound. I've spend most of my day trying to figure out what the problem and I've tried different combinations but none of them seem to work. Is there anyone who can try to help me?
Thanks.
You need two properties on your view model: one that will contain the selected group ids and one that will contain the list:
public class UsersViewModel
{
public IEnumerable<SelectListItem> Groups { get; set; }
public IEnumerable<string> SelectedGroupIds { get; set; }
}
and then you would use the ListBoxFor
helper to allow for multiple choices:
<%= Html.ListBoxFor(
m => m.SelectedGroupIds,
new SelectList(Model.Groups, "Value", "Text"),
new { @class = "dropDownGroups" }
) %>
Now assuming the following view model is passed to the view:
public ActionResult Index()
{
var model = new UsersViewModel
{
// TODO: Use a repository to fetch those values
// and map them to the view model
Groups = new[]
{
new SelectListItem { Value = "1", Text = "group 1" },
new SelectListItem { Value = "2", Text = "group 2" },
new SelectListItem { Value = "3", Text = "group 3" },
},
// We want to preselect the last two groups in the listbox
SelectedGroupIds = new[] { "2", "3" }
};
return View(model);
}
[HttpPost]
public ActionResult Index(IEnumerable<string> selectedGroupIds)
{
// Here we will get the list of selected ids
// when the form containing the listbox is
// submitted
...
}
Then on the view the last two elements will be automatically preselected.
精彩评论