【问题标题】:Razor and Html.DropDownList: Setting selected values for a dropdown for each row in a list?Razor 和 Html.DropDownList:为列表中的每一行设置下拉列表的选定值?
【发布时间】:2011-10-19 06:04:21
【问题描述】:

这看起来应该很简单,但我不知道如何使它工作。

我的数据模型有一个“Server”表和一个“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 副本的视图模型才能设置 Selected 属性?还是因为我的 id 是整数,而 SelectItemList Value 属性是字符串,所以这是个问题?

【问题讨论】:

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


    【解决方案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>
    

    【讨论】:

      【解决方案2】:

      @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;
      
      }
      

      还请记住,只应选择一项,因此请确保如果您尝试使用某个布尔属性,则不可能将多个itemisSelected 属性设置为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 });
      }
      

      【讨论】:

        【解决方案3】:

        对于仍在寻找他答案的其他人。我必须做 3 件事才能让它发挥作用

        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 = "<" } };
          

        (用户选择“大于”、“大于或等于”等)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多