最终解决方案:
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 ?)
必须更简单吗?
答案 0 :(得分: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>
}
答案 1 :(得分:1)
要做到这一点,只需通过调整视图中的一个东西来完成Darin的答案(我遗漏了我自己的模型,但它几乎与您从示例中得出的相同):
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>
}
selectedText被视为 optionLabel ,如here所述,它始终将当前选定的值放在下拉列表中。
也许有点晚了,但我希望它可以帮助其他人:)
答案 2 :(得分: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;