Ich habe eine Liste von Usern, die ich in einer ListBox auswählbar machen möchte. Diese User sind allesamt jeweils einer Firma zugeordnet. Also hatte ich die fromme Idee, sie entsprechend ihrer Firma in der ListBox zu gruppieren. Ein Standard-Feature, welches seit Urzeiten in HTML enthalten ist. Und in ASP.NET MVC? Tja ... nix da. Genau wie schon bei WebForms, muss man sich selbst helfen.
Aber halb so wild, ist ja alles schön leicht erweiterbar und wir sind ja nicht auf den Kopf gefallen :-). Nachfolgend also ein kleines Beispiel dafür, wie man das Problem lösen kann bzw. könnte - denn ich habe mir in diesem Fall aus Zeitgründen verkniffen, einen generischen Helper zu bauen.
Das View-Model
1: public class ProjectViewModel
2: {
3:
4: public ProjectViewModel()
5: {
6: CompaniesWithEligibleUsers = new Dictionary<Company, List<User>>();
7: }
8:
9: public Dictionary<Company, List<User>> CompaniesWithEligibleUsers { get; set; }
10: public List<Guid> SelectedUsers { get; set; }
11:
12: }
Der Controller
1: public ActionResult CreateProject()
2: {
3: var model = new ProjectViewModel();
4:
5: // => TEST
6: model.SelectedUsers = new List<Guid>();
7: model.SelectedUsers.Add(new Guid("2EEAA0EF-F346-4DF2-B2BE-4CC29343E6F4")); // Danny
8: model.SelectedUsers.Add(new Guid("6755B9F0-07AF-48B3-9F68-63A2F4A74402")); // Patricia
9:
10: var companies = CompanyService.GetCompaniesByClient(CurrentClient.ID);
11: foreach (var company in companies)
12: {
13: model.CompaniesWithEligibleUsers.Add(company, UserService.GetUsersByCompany(company.ID));
14: }
15:
16: return View(model);
17: }
Der View
1: <fieldset>
2: <legend></legend>
3: <%= Html.LabelFor(m => m.SelectedUsers, "Zugriff für")%>
4: <%= Html.GroupedUsersListBox("SelectedUsers", Model.SelectedUsers, Model.CompaniesWithEligibleUsers)%>
5: </fieldset>
Die Erweiterung
1: public static string GroupedUsersListBox<TModel>(this HtmlHelper<TModel> htmlHelper, string name,
2: List<Guid> selection, Dictionary<Company, List<User>> source)
3: {
4:
5: var html = new StringBuilder();
6: html.AppendLine(string.Format("<select name=\"{0}\" id=\"{0}\" multiple=\"multiple\">", name));
7:
8: foreach (var group in source)
9: {
10: html.AppendLine(string.Format("<optgroup label=\"{0}\">", group.Key.Name));
11: foreach (var user in group.Value)
12: {
13: var selectedText = selection.Any(u => u == user.ID) ? " selected=\"selected\"" : string.Empty;
14: html.AppendLine(string.Format("<option value=\"{0}\" label=\"{1}\"{2}>{1}</option>", user.ID, user.FullName, selectedText));
15: }
16: html.AppendLine(string.Format("</optgroup>"));
17: }
18:
19: html.AppendLine("</select>");
20:
21: return html.ToString();
22:
23: }
Das Ergebnis
