简体   繁体   English

ASP.NET MVC:DropDownListFor不选择任何选项

[英]ASP.NET MVC: DropDownListFor doesn't select any option

I have this to populate a drop down list in an ASP.NET MVC view. 我用它来填充ASP.NET MVC视图中的下拉列表。

<%= Html.DropDownListFor(model => model.Bikes,
      Model.Bikes.Select(
      x => new SelectListItem {
               Text = x.Name,
               Value = Url.Action("Details", "Bike", new { bikeId = x.ID }),
               Selected = x.ID == Model.ID,
           })) %>

Debugging this I can see that the Selected property is set to true when it should be. 对此进行调试,可以看到应该将Selected属性设置为true But when the view is rendered, none of the options in the list is selected. 但是,呈现视图时,列表中的所有选项均未选中。 I realize that this could be done with another overload of DropDownListFor but I really want to get this version working. 我意识到可以通过DropDownListFor另一个重载来完成此操作,但我真的很想让此版本正常工作。

Any ideas? 有任何想法吗?

The reason your selected value doesn't work is because you are using Urls as option values but specifying Model.ID in the Selected clause. 您选择的值不起作用的原因是因为您使用Urls作为选项值,但在 Selected子句中指定了 Model.ID

Try like this: 尝试这样:

 
 
 
  
  <%= Html.DropDownListFor( model => model.Bikes, new SelectList(Model.Bikes, "Id", "Name", Model.ID) )%>
 
  

"Id" indicates the property that will be used as option value while "Name" indicates the property that will be used as option label. "Id"表示将用作选项值的属性,而 "Name"表示将用作选项标签的属性。

If you want to preserve the Url.Action you could try: 如果要保留 Url.Action ,可以尝试:

 
 
 
  
  <%= Html.DropDownListFor( model => model.Bikes, new SelectList(Model.Bikes.Select(x => new { Id = x.Id, Name = Url.Action("Details", "Bike", new { bikeId = x.ID }) }), "Id", "Name", Model.ID) )%>
 
  

You will notice that I've inverted the Name and Id as it seemed more logical to use the model Id as option value. 您会注意到,我已经颠倒了Name和Id,因为使用模型Id作为选项值似乎更合逻辑。


UPDATE: 更新:

The reason this doesn't work is because you are binding to an IEnumerable (the first argument of the DropDownListFor helper). 这不起作用的原因是因为您绑定到IEnumerableDropDownListFor帮助器的第一个参数)。 It should be a scalar property while you are using the same model.Bikes collection: 使用相同model.Bikes时,它应该是标量属性。

 <%= Html.DropDownListFor( model => model.SelectedBikeValue, Model.Bikes.Select( x => new SelectListItem { Text = x.Name, Value = Url.Action("Details", "Bike", new { bikeId = x.ID }), Selected = x.ID == Model.ID, } )) %> 

My remark about not using Urls as option values stands true. 我关于不使用Urls作为选项值的说法是正确的。

I've had so many troubles with this concept. 我对这个概念有很多麻烦。 It especially manifests itself when you cannot pass it "name" property from the model that contains that property in an object, because such object name is automatically prepended to the name. 当您无法从对象中包含该属性的模型中传递“名称”属性时,它会特别显示出来,因为此类对象名称会自动添加到名称中。 This is crazy. 这太疯狂了。 After wasting many hours trying to figure this one out I just gave up and wrote my own Drop-Down extension which I publish here. 在花了很多时间试图弄清楚这一点之后,我放弃了,写了我自己的Drop-Down扩展,并在这里发布。 It is very simple and it works just fine. 这非常简单,效果很好。

    public static MvcHtmlString SimpleDropDown(this HtmlHelper helper, object attributes, IEnumerable<SelectListItem> items, bool disabled = false)
    {
        XElement e = new XElement("select",
            items.Select(a => {
                XElement option = new XElement("option", a.Text);
                option.SetAttributeValue("value", a.Value);
                if (a.Selected)
                    option.SetAttributeValue("selected", "selected");
                return option;
            })
            );

        if (attributes != null)
        {
            Dictionary<string, string> values = (from x in attributes.GetType().GetProperties() select x).ToDictionary(x => x.Name, x => (x.GetGetMethod().Invoke(attributes, null) == null ? "" : x.GetGetMethod().Invoke(attributes, null).ToString()));
            foreach(var v in values)
                e.SetAttributeValue(v.Key, v.Value);
        }

        if (disabled)
            e.SetAttributeValue("disabled", "");

        return new MvcHtmlString(e.ToString());
    }

Also, I put flag disabled as an extra parameter, because if you want to bind to it via the standard anonymous list of attributes, it can be quite a hassle. 此外,我将禁用标志设置为一个额外的参数,因为如果您想通过标准的匿名属性列表将其绑定,则可能会很麻烦。

Below is an example of how I use it at the moment. 下面是我目前如何使用它的示例。 I translate a dictionary into a list of SelectListItem, but it can be just a simple list. 我将字典翻译成SelectListItem的列表,但它可能只是一个简单的列表。

@Html.SimpleDropDown(new { id="EOM", name = "EOM", @class = "topBox" }, Model.EOM.Select(x => new SelectListItem { Text = x.Value, Value = x.Key.ToString(), Selected = Model.EOM.Selected == x.Key }), !Model.EOM.Available)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM