Asp.net mvc 3 pre-select Html.DropDownListFor не работает в ботаническом ужине
Изучение выпадающих списков, я пытаюсь добавить страницу создания RSVP для nerddinner, как в блог Скотта Гуга с Html.DropDownListДля перечисления доступных обедов,
Я могу получить раскрывающийся список, но я не могу получить раскрывающееся меню, чтобы выбрать значение ( "Sample Dinner 2" ), которое я хочу. Я использую инициализатор для посева нескольких объектов обеда в db. База данных представляет собой sql ce 4 с использованием первого подхода к коду EF. Извините, я знаю, что это общая проблема и ненависть спросить, но честно потратили довольно много времени на это, но не могу заставить ее работать:
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>
Таким образом, вы не выбираете выпадающий список со значением "Sample Dinner 2" при загрузке страницы. Список отображает ok и устанавливает правильный 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. Я думаю, что это называется привязкой.
Ответы
Ответ 1
После чтения здесь и здесь, я, наконец, понимаю как HtmlDropDownlistFor автоматически выбирает правильный элемент в раскрывающемся списке на основе вашей модели - выбор идентификатора lunchID в 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);
}
Ответ 2
Конструктор SelectList
, который вы используете, должен предоставить выбранное значение, но вы предоставляете выделенный текст. Вы можете попробовать:
int selected = 2;
Ответ 3
Html.DropDownList работает только в том случае, если связанное свойство является int. Любой другой тип, такой как имя enum, приведет к тому, что он по умолчанию будет первым.
Добавьте свойство в свою модель, введите 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 будет синхронизироваться просто отлично.
Ответ 4
Пожалуйста, позаботьтесь, если есть QUERY STRING с тем же именем, это переопределит это поведение, Не уверен в HIDDEN FIELDS с тем же именем.
например.
DropDownListFor будет использовать значение Строка запроса DinnerID, если найдено
Ответ 5
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" , это будет использоваться как значение модели
- Если нет состояния модели И Html.ViewData.Eval( "XyField" ) возвращает не null, это значение будет использоваться в качестве значения модели.
- Если найденное значение модели не равно null, оно будет преобразовано в строку, используя CultureInfo.CurrentCulture, и это значение сравнивается с вашими значениями SelectListItem, чтобы предварительно выбрать параметры списка.
Внимание: если вы сохранили свой список выбора в ViewBag.XyField, он будет найден до того, как будет получен доступ к модели. Не хотите сравнивать "selectList.ToString()" с "selectList [i].Value", чтобы предварительно выбрать ваши параметры. Сохраните свой список выбора в другом месте!
Самое забавное: вы можете использовать DropDownListFor с неявным списком выбора, точно так же, как вы ожидаете от DropDownList(). В этом случае вы даже сохраните свой список в ViewBag.XyField. Чтобы выполнить эту работу, вам просто нужно вызвать помощника с нулевым значением в качестве второго параметра: DropDownListFor (m = > m. XyField, null)
Затем список выбора вытягивается из ViewBag.XyField, и шаг 3 в приведенном выше списке пропускается. Итак, если XyField находится в состоянии модели, это будет иметь приоритет перед вашими выбранными свойствами в списке выбора, но в противном случае список выбора будет использоваться "как есть".
Привет
Rolf