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

发布于 2024-09-11 17:45:53 字数 547 浏览 3 评论 0原文

我用它来填充 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,
           })) %>

对此进行调试,我可以看到 Selected 属性在应该设置为 true 时被设置为 true 。但是当渲染视图时,列表中的任何选项都不会被选择。我意识到这可以通过 DropDownListFor 的另一个重载来完成,但我真的想让这个版本正常工作。

有什么想法吗?

I have this to populate a drop down list in an ASP.NET MVC view.

<%= 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. 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.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

大海や 2024-09-18 17:45:53

您选择的值不起作用的原因是您使用 URL 作为选项值,但在 Selected 子句中指定 Model.ID

尝试像这样:

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

"Id" 表示将用作选项值的属性,而 "Name" 表示将用作选项标签的属性。

如果您想保留 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)
)%>

您会注意到我已经颠倒了名称和 Id,因为使用模型 Id 作为选项值似乎更合乎逻辑。


更新:

这不起作用的原因是您绑定到 IEnumerableDropDownListFor 帮助器的第一个参数)。当您使用相同的 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,
        }
)) %>

我关于不使用 URL 作为选项值的评论是正确的。

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.

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.

If you want to preserve the Url.Action you could try:

<%= 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.


UPDATE:

The reason this doesn't work is because you are binding to an IEnumerable (the first argument of the DropDownListFor helper). It should be a scalar property while you are using the same model.Bikes collection:

<%= 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.

情何以堪。 2024-09-18 17:45:53

我在这个概念上遇到了很多麻烦。当您无法从对象中包含该属性的模型传递“name”属性时,它尤其会表现出来,因为此类对象名称会自动添加到名称前面。这太疯狂了。在浪费了很多时间试图解决这个问题之后,我放弃了并编写了我自己的下拉扩展,我将其发布在这里。它非常简单并且工作得很好。

    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());
    }

另外,我将标记 disabled 作为额外参数,因为如果您想通过标准匿名属性列表绑定到它,这可能会很麻烦。

下面是我目前如何使用它的示例。我将字典翻译成 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)

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. 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.

@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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文