asp.net mvc 3 предварительно выберите Html.DropDownList для не работающего на обеде ботаника - PullRequest
14 голосов
/ 26 января 2011

Узнав о выпадающих списках, я пытаюсь добавить страницу создания RSVP для nerddinner, как в блоге Скотта Гу с Html.DropDownListFor, в котором перечислены доступные обеды.

Я могу заполнить раскрывающийся список, но не могу получить раскрывающийся список для предварительного выбора нужного значения («Обеденный ужин 2»). Я использую инициализатор, чтобы посеять несколько обеденных предметов в БД. База данных - это sql ce 4 с использованием EF 'code first подхода'. Извините, я знаю, что это очень распространенная проблема, и мне неприятно спрашивать, но, честно говоря, я потратил довольно много времени на это, но не могу заставить ее работать:

ViewModel

public class RSVPViewModel
{
    public SelectList DinnersList { get; set; }
    public RSVP Rsvp { get; set; }
    public string SelectedItem { get; set; }
}

Контроллер

    //
    //GET: /RSVP/Create

    public ActionResult Create()
    {
        RSVP rsvp = new RSVP();
        string selected = "Sample Dinner 2";
        var typeList = new SelectList(dbc.Dinners.ToList(), "DinnerID", "Title", selected);

        var viewModel = new RSVPViewModel { DinnersList = typeList, Rsvp = rsvp, SelectedItem = selected };

        return View("Create", viewModel);
    }

Посмотреть

@Html.DropDownListFor(model => model.Rsvp.DinnerID, Model.DinnersList)

HTML Результат

<select data-val="true" data-val-number="The field DinnerID must be a number." data-val-required="The DinnerID field is required." id="Rsvp_DinnerID" name="Rsvp.DinnerID">
     <option value="1">Sample Dinner 1</option>
     <option value="2">Sample Dinner 2</option>
</select>

Таким образом, предварительный выбор раскрывающегося списка со значением «Образец ужина 2» не выполняется при загрузке страницы. Список отображается нормально и устанавливает правильный DinnerID, когда я делаю выбор и нажимаю Отправить.

Пытается это также:

@Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList)

но не устанавливает или не привязывает к Rsvp.DinnerID.

Это предварительно выбирает из списка, но не привязывает (или не устанавливает Rsvp.DinnerID)

@Html.DropDownList("DinnersList")

Я хочу сохранить его в mvc3, поэтому хочу реализовать его со строгим типом, используя подход ViewModel (без ViewData) и предпочтительно с использованием Html.DropDownListFor (не Html.DropDownList). В этом случае Viewbag кажется ненужным.

Спасибо!

Edit1

Думая, что я должен использовать selectList из selectListItems, я попробовал этот подробный подход:

RSVP rsvp = new RSVP();
string selected = "2";
List<SelectListItem> dinners = new List<SelectListItem>();

foreach (Dinner dinner in dbc.Dinners.ToList())
{
    SelectListItem slDinner = new SelectListItem();
    slDinner.Value = dinner.DinnerID.ToString();
    slDinner.Text = dinner.Title;
    slDinner.Selected = (slDinner.Value == selected);
    dinners.Add(slDinner);
 }

 var dinnersList = new SelectList(dinners, "Value", "Text", selected);
 var viewModel = new RSVPViewModel { DinnersList = dinnersList, Rsvp = rsvp, SelectedItem = selected };

Однако по-прежнему нет работы. Должен ли я как-то использовать свойство ViewModel SelectedItem в: @ Html.DropDownListFor ..? Что-то вроде:

@Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList)

но как мне получить выбранное значение для установки Rsvp.DinnerID. Я думаю, что это называется обязательным.

Ответы [ 5 ]

12 голосов
/ 26 января 2011

После прочтения здесь и здесь я, наконец, понимаю, как HtmlDropDownlistFor автоматически выбирает правильный элемент в раскрывающемся списке на основе вашей модели - выбирает идентификатор обеда в RSVP (внешний ключ для dinner.dinnerID) приведет к тому, что раскрывающийся список, содержащий список Dinner.DinnerID, будет предварительно выбирать это значение. Нет необходимости пока Я думаю, что для selectedValue в SelectList или ViewModel.

Решение:

    //
    //GET: /RSVP/Create

    public ActionResult Create()
    {
        //automatically preselects matching DinnerID in the Dinner dropdownlist            
        var rsvp = new RSVP {DinnerID = 2 };

        var typeList = new SelectList(dbc.Dinners.ToList(), "DinnerID", "Title");
        var viewModel = new RSVPViewModel { DinnersList = typeList, Rsvp = rsvp};

        return View("Create", viewModel);
    }
3 голосов
/ 26 января 2011

Конструктор SelectList , который вы используете, должен предоставлять выбранное значение, но вы предоставляете выделенный текст.Вы можете попробовать:

    int selected = 2;
2 голосов
/ 14 марта 2013

Пожалуйста, позаботьтесь, если есть QUERY STRING с с тем же именем , это переопределит это поведение, Не уверен насчет скрытых полей с тем же именем.

1007 * Е.Г. *

DropDownListFor будет использовать значение Строка запроса DinnerID, если найден

2 голосов
/ 19 сентября 2011

Html.DropDownList работает, только если связанным свойством является int. Любой другой тип, такой как именованное перечисление, приведет к тому, что по умолчанию будет использоваться первый элемент.

Добавьте свойство к вашей модели, введите int, которое переносит перечисление, которое вы пытаетесь сохранить:

public myEnumType myProperty {get; set;} // don't bind this to Html.DropDownList

public myEnumType myPropertyAsInt {
    get {return (int)this.myProperty; }
    set {this.myProperty = (myEnumType)value; }
} // bind this instead

Нет необходимости использовать Selected в вашем SelectList - Html.DropDownList синхронизируется очень хорошо.

1 голос
/ 14 июня 2012

Html.DropDownList принимает свойства int, DropDownListFor тоже, но вы должны быть осторожны в своих действиях.Я изучил SelectExtensions.cs из ASP.NET MVC 3 и обнаружил следующее:

Когда вы используете DropDownList («XyField», «default») для создания DropDown, вы должны поместить список выбора в ViewBag.XyField и DropDownList () обрабатывают это правильно.

Когда вы используете DropDownListFor (m => m.XyField, ...), вы можете явно передать список выбора, например: DropDownListFor (m => m. XyField , ViewBag. XyFieldList как IEnumerable)

При этом происходит следующее:

  • Второй параметр DropDownListFor (...) будет использоваться в качестве источника для опций
  • Если есть запись ModelState для "XyField", это будет использоваться как значение модели
  • Если нет состояния модели ANDHtml.ViewData.Eval ("XyField") возвращает не нуль, это значение будет использоваться в качестве значения модели.
  • Если найденное значение модели не равно нулю, оно будет преобразовано в строку с использованием CultureInfo.CurrentCulture, и это значение сравнивается с вашим SeleЗначения ctListItem для предварительного выбора параметров списка.

Внимание: если вы сохранили свой список выбора в ViewBag.XyField, он будет найден до обращения к модели. Не хотите сравнивать "selectList.ToString() «with» selectList [i] .Value »для предварительного выбора параметров.Сохраните свой список выбора в другом месте!

Самое смешное, что вы МОЖЕТЕ использовать DropDownListFor с неявным списком выбора, так же, как вы ожидаете его от DropDownList ().В этом случае вы даже сохраните свой список в ViewBag.XyField.Чтобы это работало, вам просто нужно вызвать помощника с нулевым значением в качестве второго параметра: DropDownListFor (m => m. XyField , null)

Затем список выбора извлекается из ViewBag.XyField и шаг 3 в списке выше пропускаются.Таким образом, если XyField находится в состоянии модели, он будет иметь приоритет перед вашими собственными выбранными свойствами в списке выбора, но в противном случае список выбора будет использоваться «как есть».

Greetings Rolf

...