ASP.NET MVC: DropDownListFor не выбирает никакой опции - PullRequest
5 голосов
/ 28 июля 2010

У меня есть это, чтобы заполнить раскрывающийся список в представлении 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, когда оно должно быть,Но когда представление отображается, ни один из параметров в списке не выбран.Я понимаю, что это может быть сделано с другой перегрузкой DropDownListFor, но я действительно хочу, чтобы эта версия работала.

Есть идеи?

Ответы [ 2 ]

5 голосов
/ 28 июля 2010

Причина, по которой выбранное вами значение не работает, заключается в том, что вы используете URL-адреса в качестве значений параметров, но задаете Model.ID в предложении Selected.

Попробуйте вот так:

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

"Id" указывает свойство, которое будет использоваться в качестве значения параметра, а "Name" указывает свойство, которое будет использоваться в качестве метки параметра.

Если вы хотите сохранить Url.Action, вы можете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)
)%>

Вы заметите, что я инвертировал Name и Id, так как было более логично использовать Id модели в качестве значения опции.


ОБНОВЛЕНИЕ:

Причина, по которой это не работает, заключается в том, что вы привязываетесь к IEnumerable (первый аргумент помощника DropDownListFor).Это должно быть скалярное свойство, когда вы используете одну и ту же коллекцию 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-адреса в качестве значений параметров, соответствует действительности.

0 голосов
/ 20 сентября 2013

У меня было так много проблем с этой концепцией. Это особенно проявляется, когда вы не можете передать его "имя" свойство из модели, содержащей это свойство в объекте, потому что такое имя объекта автоматически добавляется к имени. Это безумие. Потратив много часов, пытаясь выяснить это, я просто сдался и написал свое собственное расширение Drop-Down, которое я публикую здесь. Это очень просто и отлично работает.

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

Кроме того, я поставил флаг отключен в качестве дополнительного параметра, потому что, если вы хотите связать его с помощью стандартного анонимного списка атрибутов, это может быть довольно хлопотно.

Ниже приведен пример того, как я использую его в данный момент. Я перевожу словарь в список 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)
...