2013-02-19 3 views
1

Окончательное решение:SelectList выбранное значение

public class UpdateUser 
{ 
    public IEnumerable<string> SelectedRoles { get; set; } 
    public IEnumerable<SelectListItem> DropDownRoles { get; set; } 
} 

...

var roles = context.Roles.Select(x => x.RoleName).ToList(); 
UpdateUser userToUpdate = new UpdateUser 
{ 
    SelectedRoles = user.Roles.Select(x => x.RoleName), 
    DropDownRoles = new SelectList(roles, user.Roles) 
}; 

HTML

@Html.ListBoxFor(x => x.SelectedRoles, Model.DropDownRoles) 

============ =============

У меня есть выпадающий список для отображения пользовательских ролей, как так:

HTML

@Html.TextBoxFor(x => x.Roles) 
    @Html.DropDownList("roles", ViewData["roles"] as SelectList) 

Контроллер

var user = context.Users.Include(x => x.Roles).Where(x => x.UserId == id).FirstOrDefault(); 
ViewData["roles"] = new SelectList(context.Roles, "RoleId", "RoleName"); 

Проблема заключается в том, что я не могу понять, как я мог установить выбранное значение в раскрывающемся списке. Я подумал, что, возможно, я мог бы использовать Lambda Expression, чтобы поставить соответствующую роль в верхней части списка, а затем в алфавитном порядке.

 var roles = context.Roles 
      .ToList() 
      .OrderBy(? matching role then other selectable roles ?) 

Должно быть, проще?

ответ

4

Не используйте то же значение, что и ключ ViewData, и выбранное значение для раскрывающегося списка. Попробуйте так:

@Html.DropDownList("selectedRole", ViewData["roles"] as SelectList) 

, а затем ваш POST действие контроллера может принять это в качестве параметра:

[HttpPost] 
public ActionResult Index(string selectedRole) 
{ 
    ... 
} 

и если у вас есть другие поля внутри формы, вы могли бы сгруппировать их в модели представления:

public class MyViewModel 
{ 
    public string SelectedRole { get; set; } 
    public string SomeOtherField { get; set; } 
} 

, а затем у вашего действия контроллера выберите эту модель в качестве параметра. А так как теперь у вас есть модель представления, давайте в полной мере воспользоваться этим и избавиться от страшного слабо типизированный ViewData:

public class MyViewModel 
{ 
    public string SelectedRole { get; set; } 
    public IEnumerable<SelectListItem> Roles { get; set; } 

    public string SomeOtherField { get; set; } 
    public string YetAnotherField { get; set; } 
} 

и тогда вы могли бы иметь действие GET заполнить этот вид модели:

public ActionResult Index() 
{ 
    var model = new MyViewModel(); 
    model.Roles = new SelectList(context.Roles, "RoleId", "RoleName"); 
    return View(model); 
} 

[HttpPost] 
public ActionResult Index(MyViewModel model) 
{ 
    ... 
} 

и тогда ваш взгляд может быть сильно типизированных к модели представления:

@model MyViewModel 
@using (Html.BeginForm()) 
{ 
    ... 
    @Html.DropDownListFor(x => x.SelectedRole, Model.Roles) 
    ... 
    <button type="submit">OK</button> 
} 
+0

Что если пользователь имеет более чем 1 роль? 'public IEnumerable SelectedRole {get; задавать; } 'Итак, для каждой роли пользователя у нас есть новый раскрывающийся список. – user1883004

+0

Точно: 'public IEnumerable SelectedRoles {get; задавать; } '. А затем используйте 'Html.ListBoxFor (x => x.SelectedRoles, Model.Roles)' вместо 'Html.DropDownListFor (x => x.SelectedRole, Model.Roles)' в вашем представлении, чтобы разрешить множественный выбор , –

+0

Спасибо за помощь до сих пор, почти там, мне просто нужно установить выбранные значения, Позвольте мне редактировать OP. – user1883004

0

SelectList содержит список SelectListItem объектов, каждый из которых имеет Selected собственности. Таким образом, вы могли бы сделать что-то вроде:

var user = context.Users.Include(x => x.Roles).Where(x => x.UserId == id).FirstOrDefault(); 
var temp = new SelectList(context.Roles, "RoleId", "RoleName"); 
temp.First(x => x.Value.Equals(IdOfSelectedObject)).Selected = true; 
ViewData["roles"] = temp; 
1

Ответ Дарина полностью и ясен, это помогло мне в моих поисках. Однако я просто должен был сделать еще одно дополнение для строго типизированного представления. В моем проекте я заполняю SelectList определенными ролями для определенного пользователя. Эти роли были сохранены в базе данных.При редактировании (изменение свойств пользователя, включая эту роль), я хотел бы, чтобы первоначально настроенная роль отображалась в качестве значения .

Чтобы сделать это, просто завершить Дарин свой ответ, регулируя еще одну вещь к виду (я оставил мою собственную модель, но это почти так же, как вы можете понять из примера):

model MyViewModel 
@using (Html.BeginForm()) 
{ 
    ... 
    @{ 
     var selectedItem = Model.Roles.Where(role => role.Value.AsInt().Equals(...).FirstOrDefault(); 
     var selectedText = selectedItem != null ? selectedItem.Text : null; 
     Html.DropDownListFor(x => x.SelectedRole, Model.Roles, selectedText) 
    } 

    ... 
    <button type="submit">OK</button> 
} 

Выбранный текст считается optionLabel, как описано here, который всегда будет помещать текущее выбранное значение в раскрывающийся список.

Возможно, чуть-чуть поздно, но я надеюсь, что это может помочь другим :)

Смежные вопросы