Razor和Html.DropDownList:为列表中的每一行的下拉列表设置选定的值?

时间:2011-08-03 15:52:33

标签: asp.net-mvc-3 drop-down-menu razor selecteditem

这看起来应该很简单,但我无法弄清楚如何让它发挥作用。

我的数据模型有一个“服务器”表和一个“ServerType”表。两个表的PK都是整数,Server有一个字段ServerTypeId,它是ServerType.Id的fk。

我有一个输入到IEnumerable的Razor List.cshtml:

@model IEnumerable<Server>
<table border="1">
    <tr>
        <th>
            Server Type
        </th>
        <th>
            Name
        </th>
    </tr>
    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DropDownListFor(modelItem => item.ServerTypeId, (IEnumerable<SelectListItem>)ViewData["ServerType"])
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
        </tr>
    }
</table>

我的控制器有:

    public ActionResult List()
    {
        var s = GetServers();
        ViewData["ServerType"] = GetServerTypes();
        return View("List", s);
    }

    private List<SelectListItem> GetServerTypes()
    {
        string id;
        SelectListItem si;
        List<SelectListItem> sl = new List<SelectListItem>();
        IQueryable<ServerType> items = (from t in _entities.ServerTypes select t);
        foreach (var item in items)
        {
            id = item.Id.ToString();
            si = new SelectListItem { Value = id, Text = item.Description };
            sl.Add(si);
        }
        return sl;
    }

显示数据,但未选中下拉列表中的值。我已经尝试了Html.DropDownList和Html.DropDownListFor,它们具有ViewData属性的名称的不同排列,最后有和没有Id。

我是否需要创建一个包含ServerType副本的viewmodel才能设置Selected属性?或者它是一个问题因为我的id是整数,而SelectItemList Value属性是一个字符串?

3 个答案:

答案 0 :(得分:1)

在GetServerTypes()中List的填充中,您是否指定选择了任何项目。这是您需要手动执行的操作,因为MVC3不够智能,无法在DropDownListFor方法中为您推断它。由于您没有使用单一模型,因此更加复杂。

更好的方法可能是:

(请记住下面的代码,我假设Server类有一个名为“Id”的主ID)

对于控制器代码:

public ActionResult List()
{
    IEnumerable<Server> s = GetServers();
    ViewData["ServerTypes"] = GetServerTypes(s);
    return View("List", s);
}

private Dictionary<int, SelectList> GetServerTypes(IEnumerable<Server> s)
{
    Dictionary<int, SelectList> sl = new Dictionary<int, SelectList>();
    IEnumerable<ServerType> items = (from t in _entities.ServerTypes select t);
    foreach (Server srv in s) {
      sl.Add(srv.Id, new SelectList(items, "Id", "Description", srv.ServerTypeId));
    }
    return sl;
}

对于视图代码:

(另请注意下面我如何更正lambda函数中使用的参数)

@model IEnumerable<Server>
<table border="1">
    <tr>
        <th>
            Server Type
        </th>
        <th>
            Name
        </th>
    </tr>
    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DropDownListFor(modelItem => modelItem.ServerTypeId, (IEnumerable<SelectListItem>)(ViewData["ServerTypes"][item.Id]))
            </td>
            <td>
                @Html.DisplayFor(modelItem => modelItem.Name)
            </td>
        </tr>
    }
</table>

答案 1 :(得分:1)

@TreyE正确地指出,您从未指定在视图中显示时应选择任何特定的选择列表项。

有几种方法可以做到这一点。首先是使用SelectList对象并使用它的构造函数,它允许您传入应该选择的对象,它是重载SelectList(IEnumerable, String, String, Object) MSDN SelectList

SelectList仅支持.NET 3.5+,但仅供参考。

其次,在GetServerTypes()你可以写:

private List<SelectListItem> GetServerTypes()
{
    List<SelectListItem> sl = new List<SelectListItem>();
    IQueryable<ServerType> items = (from t in _entities.ServerTypes select t);

    foreach (var item in items)
        sl.add(new SelectListItem { Value = item.id, Text = item.Description, Selected = item.isSelected } );

    return sl;

}

另外请记住,只应选择一个项目,因此请确保如果您尝试使用某个布尔属性,则不可能有多个item可以将其isSelected属性设置为true

或者,如果您需要使用某种类型的if语句来决定Selected = true(即您的项目没有isSelected布尔值),那么您可以在foreach循环中添加它。

foreach(var item in items)
{
    if //condition
      sl.Add(new SelectListItem { Value = item.id, Text = item.Description, Selected = true });

    else
      sl.Add(new SelectListItem { Value = item.id, Text = item.Description, Selected = false });
}

答案 2 :(得分:1)

对于仍在寻找的人,他回答。我必须做三件事来让这个工作

  1. 用户@for代替@foreach。这样它就有一个可以工作的索引 在命名的时候。
  2. 没有ViewBag变量名称     与财产相同。它试图帮助你解决问题     如果他们有相同的名字,请尽早。
  3. 在SelectList的构造函数中传递当前值。我的     代码最终为:

       @for (int i = 0; i < Model.Count; i++)
       {
           <tr>
               <td>          
          @Html.DropDownListFor(modelItem => Model[i].operatorToken, 
    new SelectList(ViewBag.operatorTokensList, "Value", "Text", Model[i].operatorToken), 
    "Select", htmlAttributes: new { @class = "form-control" })
    
    
    
    ...ect...
        }
    

    注意SelectList()的第4个参数设置选定的值。

    我的operatorTokensList的价值是:

    new[] { new { Value = ">", Text = ">" }, 
                   new { Value = ">=", Text = ">=" },
                   new { Value = "=", Text = "=" },
                   new { Value = "<=", Text = "<=" },
                   new { Value = "<", Text = "<" } };
    
  4. (用户选择“大于”,“大于或等于”等)。