获取ASP.NET MVC DropdownLists上的删除

ASP.NET MVC中的Dropdownlists似乎对网络形式世界新鲜的开发人员造成相当数量的混淆。本文希望为您提供所有(井,最多)您需要知道的东西,以便在ASP.NET MVC中工作的DropdownList。

如果您正在寻找有关管理多项选择或支持枚举作为下拉的数据源的信息,则应查看我的新帖子: ASP.NET MVC. DropdownLists - 多个选择和枚举支持。否则读取在ASP.NET MVC中的所有内容下拉列表上的划线。

dropdownlist,combobox,称它是你喜欢的,但它总是呈现 HTML选择元素. It has an opening<select>tag, and a closing</select>tag. In between, each "ListItem" is housed within an<option>tag. Optionally, they may be subdivided into<optgroup>elements for logical separation of related options. If you provide a 价值 属性到一个选项,即在提交外接选择元素的表单时发布的值。如果你省略了 价值 属性,选项的文本值已发布。

例如,最简单,例如,如果您有一个静态列表需要在下拉列表中出现的项目,可以简单地将它们视为HTML:

<select name="year">
  <option>2010</option>
  <option>2011</option>

  <option>2012</option>
  <option>2013</option>
  <option>2014</option>

  <option>2015</option>
</select>

或者,如果列表有点动态,请说明您是否需要确保开始年份递增1,每个新年增加1's Day:

[WebForms]

<select name="year">

  <option><%= DateTime.Now.Year %></option>
  <option><%= DateTime.Now.AddYears(1).Year %></option>

  <option><%= DateTime.Now.AddYears(2).Year %></option>
  <option><%= DateTime.Now.AddYears(3).Year %></option>

  <option><%= DateTime.Now.AddYears(4).Year %></option>
  <option><%= DateTime.Now.AddYears(5).Year %></option>

</select>

[Razor]

<select name="year">

  <option>@DateTime.Now.Year</option>
  <option>@DateTime.Now.AddYears(1).Year</option>

  <option>@DateTime.Now.AddYears(2).Year</option>
  <option>@DateTime.Now.AddYears(3).Year</option>
  <option>@DateTime.Now.AddYears(4).Year</option>
  <option>@DateTime.Now.AddYears(5).Year</option>

</select>

甚至:

[WebForms]  

<select name="year">
  <% for (var i = 0; i < 6; i++){%>

    <option><%= DateTime.Now.AddYears(i).Year %></option>
  <%}%>
</select>

[Razor]  

<select name="year">
  @for (var i = 0; i < 6; i++){

    <option>@(DateTime.Now.AddYears(i).Year)</option>
  }
</select>

以上所有HTML和最终结果都呈现完全相同的HTML和最终结果

If your data comes from a database, you will more likely use one of the 8 overloads of the Html.DropDownList() extension method to create your DropDown. I won'T覆盖所有过载,但值得看看主要的过载。第一个 -

public static string DropDownList(this HtmlHelper htmlHelper, string name)

- 只接受一个字符串。现在,文档目前表示字符串应该是表单字段的名称,它是不是't particularly helpful. In fact, not only does it provide the resulting select element with a name and an id, but it also acts as the look-up for an item in the ViewBag having the same dynamic property as the string provided. This ViewBag property is then bound to the helper to create the <option> items. Consequently, the ViewBag property must be a collection of SelectListItems. Here'如何使用NorthWind示例数据库获取类别,使用实体框架使用第一个超载传递给DropdownList:

public ActionResult Index()
{
  var db = new NorthwindEntities();
  IEnumerable<SelectListItem> items = db.Categories
    .Select(c => new SelectListItem
                   {
                     Value = c.CategoryID.ToString(), 
                     Text = c.CategoryName
                   });
  ViewBag.CategoryID = items;
  return View();
}


Notice that each SelectListItem must have aValueand aTextproperty assigned. These are bound at run-time to the value attribute of the option elements and the actual text value for the option. Notice also the odd name given to the ViewBag dynamic property "CategoryID"。原因是,progroundID是在提交表单时将传递的值,因此命名为此是有意义的。在视图中,使用过载:

[WebForms]

<%= Html.DropDownList("compouttsid.") %>

[Razor]

@Html.DropDownList("compouttsid.")

然后's all that's需要呈现以下HTML:

<select id="compouttsid." name="compouttsid.">
  <option 价值="1">Beverages</option>

  <option 价值="2">Condiments</option>
  <option 价值="3">糖果</option>
  <option 价值="4">Dairy Products</option>

  <option 价值="5">Grains/Cereals</option>
  <option 价值="6">Meat/Poultry</option>
  <option 价值="7">Produce</option>

  <option 价值="8">Seafood</option>
</select>

第二个过载 -

public static string DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList)

- is one you quite often see in examples. With this overload, you can return anIEnumerable<SelectListItem>collection or aSelectListobject. We'll have a look at the View first, before seeing two methods of populating the ViewData with alternative objects:

[WebForms]  

<%= Html.DropDownList("compouttsid.", (IEnumerable<SelectListItem>) ViewBag.Categories) %>


[Razor]  

@Html.DropDownList("compouttsid.", (IEnumerable<SelectListItem>) ViewBag.Categories)


The first item to go into ViewBag will be theIEnumerable<SelectListItem>object. The code is pretty well identical to the previous example:

public ActionResult Index()
{
  var db = new NorthwindDataContext();
  IEnumerable<SelectListItem> items = db.Categories
    .Select(c => new SelectListItem
                   {
                     Value = c.CategoryID.ToString(),
                     Text = c.CategoryName
                   });
  ViewBag.Categories = items;
  return View();
}


The second passes a SelectList object to ViewBag:

public ActionResult Index()
{
  var db = new NorthwindDataContext();
  var query = db.Categories.Select(c => new { c.CategoryID, c.CategoryName });
  ViewBag.Categories = new SelectList(query.AsEnumerable(), "compouttsid.", "CategoryName");
  return View();
}


Using aSelectListis slightly tidier in the Controller, and arguably in the View. TheSelectListconstructor has a couple of overloads which accepts an object representing the selected value:

public ActionResult Index()
{
  var db = new NorthwindDataContext();
  var query = db.Categories.Select(c => new { c.CategoryID, c.CategoryName });
  ViewBag.CategoryId = new SelectList(query.AsEnumerable(), "compouttsid.", "CategoryName", 3);
  return View();
}


以上将确保这一点"Confections"当列表呈现时被选中:

默认值

到目前为止,所有示例都显示了页面加载时可见的第一个可选选项。然而,大多数情况下,默认值是可取的,这是否是空白值或向用户提示"--Select One--"或类似的。另一个过载照顾添加它 -

public static string DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, string optionLabel).

[WebForms]
<%= Html.DropDownList("compouttsid.", (SelectList) ViewBag.CategoryId, " - 选择一个 - ") %>

[Razor]
@Html.DropDownList("compouttsid.", (SelectList) ViewBag.CategoryId, " - 选择一个 - ") 

CSS和HTML属性

Four of the overloads accept parameters for applying HTML attributes to the DropDownList when it is rendered. Two of them accept IDictionary<string, object> while the other two take an object. The object is an anonymous type. The following examples will both render identical html, applying a css class selector and a client-side onchange() event:

[Webforms]  

<%= Html.DropDownList(
    "compouttsid.", 
    (SelectList)ViewBag.CategoryId, 
    " - 选择一个 - ", 
    new Dictionary<string, object>

                      {
                         {"班级", "myCssClass"}, 
                         {"onchange", "someFunction();"}
                      }) %>
                      
                      
<%= Html.DropDownList(
    "compouttsid.", 
    (SelectList)ViewBag.CategoryId, 
    " - 选择一个 - ", 
    new{  //anonymous type
          @class = "myCssClass", 
          onchange = "someFunction();"
       }) %>

[Razor]  

@Html.DropDownList(
    "compouttsid.", 
    (SelectList)ViewBag.CategoryId, 
    " - 选择一个 - ", 
    new Dictionary<string, object>

                      {
                         {"班级", "myCssClass"}, 
                         {"onchange", "someFunction();"}
                      }) 
                      
                      
@Html.DropDownList(
    "compouttsid.", 
    (SelectList)ViewBag.CategoryId, 
    " - 选择一个 - ", 
    new{ //anonymous type
          @class = "myCssClass", 
          onchange = "someFunction();"
       }) 

您应该注意到第二个版本(使用匿名类型的版本)具有调用的属性"@class"。这将呈现为文字"class",但需要前面的@签名"class" because 班级 is obviously a C# keyword. You might also wonder why there are two ways to add attributes. The second option, using the anonymous object is a lot cleaner and surely would be the sensible choice. However, for one thing, the HTML5 specification includes the ability to add custom attributes to your html mark-up. Each attribute must be prefixed with "data-". If you attempt to create a property in a C# object with a hyphen in its name, you will receive a compiler error. The Dictionary<string, object> approach will solve that problem. 更新:由于MVC 5,您可以使用属性名称中的匿名类型方法使用下划线。这些将由MVC转换为连字符。

在哪里's My AutoPostBack?

来自Web表单模型的开发人员的最常见问题之一涉及MVC中的DropdownLists的自动返回。在网络形式中,它'S易于在设计视图中选择您的DropdownList,将返回IDE中的属性面板,并将自动返回设置为TRUE,或者在控件上勾选使用自动返回选项'S智能标签。很多时候,由于它很容易,开发人员很少考虑使用自动返回时幕后发生的事情。实际上,onchange属性被添加到渲染的dropdownlist中,该roplowdownlist击中JavaScript事件处理程序,导致将丢弃下拉列表被提交的表单。该过程必须在MVC中手动完成。但它's quite simple. I'LL显示两种实现这一目标。一个将使用最新的过载(上面)为HtmlAttributes带来一个对象,另一个将显示使用jQuery,不引人注目的方式可以完成同样的事情。我没有'实际上在迄今为止的表单元素中实际上显示了下拉列表,但当然当然是一个下拉列表在一个之外大多是无用的。这里'第一个替代方案:

[WebForms]

<% using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "TheForm" })){%>

  <%= Html.DropDownList(
    "compouttsid.", 
    (SelectList) ViewData["类别"], 
    " - 选择一个 - ", 
    new{
          onchange = "document.getElementById('TheForm').submit();"
       })%>

<%}%> 

[Razor]

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "TheForm" })){

  @Html.DropDownList(
    "compouttsid.", 
    (SelectList) ViewData["类别"], 
    " - 选择一个 - ", 
    new{
          onchange = "document.getElementById('TheForm').submit();"
       })
} 

和使用jQuery的第二个:

<script type="text/javascript">
  $(function() {
    $("#CategoryID").change(function() {
      $('#TheForm').submit();
    });
  });

</script>
[WebForms]
<%using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "TheForm" })){%>

  <%=Html.DropDownList("compouttsid.", (SelectList) ViewBag.CategoryId, " - 选择一个 - ") %>
<%}%> 
[Razor]
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "TheForm" })){

  @Html.DropDownList("compouttsid.", (SelectList) ViewBag.CategoryId, " - 选择一个 - ") 
} 

工具提示

DropdownLists的现有HTMLPers集合中的任何内容都没有提供添加工具提示,以便此刻选择列表选项。通过添加一个工具提示"title"属性到列表中的每个选项。现在,这可以通过创建自己的扩展方法来实现,允许您指定每个选项元素应该具有标题,然后应用a 按照每个选项添加标题属性的值将添加到“选择”列表中。但是'是一个相当数量的工作......或者,你可以使用jquery来真正做到这一点:

<script type="text/javascript">

  $(function() {
  $("#CategoryID option").each(function() {
      $(this).attr({'title': $(this).html()});
    });
  });
</script>

强类型的助手

到目前为止,所有的例子都已说明了使用动态ViewBag集合来将来自控制器的值传递到视图。对于DropDownList,有强大类型的HTML帮助者迎合强烈键入的视图 - 具有所有IntelliSense支持和编译时检查。以下示例显示了一个称为SelectViewModel的非常简单的ViewModel类:

using System.Collections.Generic;
using System.Web.Mvc;


public class SelectViewModel
{
    public string CategoryId { get; set; }
    public IEnumerable<SelectListItem> List { get; set; }
}

Here's a sample controller action that instantiates a SelectViewModel instance and passes it to the strongly type view:

public ActionResult Index()
{
    var db = new NorthwindDataContext();

    var query = db.Categories.Select(c => new SelectListItem
                                              {
                                                  Value = c.CategoryID.ToString(), 
                                                  Text = c.CategoryName,
                                                  Selected = c.CategoryID.Equals(3)
                                              });
    var model = new SelectViewModel
                    {
                        List = query.AsEnumerable()
                    };
    return View(model);
}

Notice how the selected item is identified as the IEnumerable collection of SelectListItems is built from the database query. Finally, in the (Razor) view, the dropdown is rendered with a default option added:

@model SelectViewModel

@Html.DropDownListFor(m => m.CategoryId, Model.List, " - 选择一个 - ")