asp.net mvc 3 pre-select Html.DropDownListFor не работает в ужине ботаника

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

Я могу заполнить раскрывающийся список, но я не могу получить раскрывающийся список, чтобы предварительно выбрать значение («Образец обеда 2»), которое я хочу. Я использую инициализатор для заполнения нескольких объектов обеда в базе данных. База данных - 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>

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


person Jay    schedule 26.01.2011    source источник
comment
При пошаговом выполнении кода есть ли в списке, созданном new SelectList(...), элемент, свойство Selected которого истинно?   -  person StriplingWarrior    schedule 26.01.2011
comment
Я не уверен, что вы имеете в виду. Я не использую SelectListItems в списке выбора, поэтому я не вижу выбранное свойство? Также я читал в другом месте (stackoverflow.com/questions/2410543/), что свойство Selected игнорируется в большинстве случаев (возможно, будет работать для @ html.dropdownlist (DinnerList), но тогда не будет привязки?   -  person Jay    schedule 26.01.2011
comment
Я вижу свойство SelectedValue в typeList, значение которого равно 2, а тип - int после перехода к ответу ниже.   -  person Jay    schedule 26.01.2011


Ответы (5)


Прочитав здесь и здесь, я наконец понимаю, как HtmlDropDownlistFor автоматически выбирает правильный элемент в раскрывающемся списке на основе вашей модели - выбор ужинаID в RSVP (внешний ключ для ужина.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);
    }
person Jay    schedule 26.01.2011
comment
См. Мои руководства по DDL asp.net/mvc/tutorials/javascript/ и blogs.msdn.com/b/rickandy/archive/2012/01/09/ - person RickAndMSFT; 14.02.2012

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

    int selected = 2;
person StriplingWarrior    schedule 26.01.2011
comment
Это тоже не сработало. По-прежнему по умолчанию используется 1-й элемент в списке. Я проверил базу данных, чтобы убедиться, что есть обеденный объект с DinnerID = 2. - person Jay; 26.01.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 будет синхронизироваться нормально.

person David Steele    schedule 19.09.2011
comment
Это неверно. См. Мои руководства по DDL asp.net/mvc/tutorials/javascript/ и blogs.msdn.com/b/rickandy/archive/2012/01/09/ - person RickAndMSFT; 14.02.2012
comment
Это сработало для меня, я изначально был привязан к перечислению, но преобразование в ссылку int в этом примере привело к срабатыванию предварительного выбора элемента - person Neil; 15.08.2012

Будьте осторожны, если есть СТРОКА ЗАПРОСА с тем же именем, она переопределит это поведение. Не уверен в СКРЫТЫХ ПОЛЯХ с таким же именем.

E.g.

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

person Ahmed Eid Yamany    schedule 14.03.2013

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

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

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

Когда вы это сделаете, произойдет следующее:

  • Второй параметр DropDownListFor (...) будет использоваться в качестве источника для параметров.
  • Если есть запись ModelState для «XyField», она будет использоваться как значение модели.
  • Если состояние модели отсутствует И Html.ViewData.Eval ("XyField") возвращает не null, это значение будет использоваться в качестве значения модели.
  • Если найденное значение модели не является нулевым, оно будет преобразовано в строку с использованием CultureInfo.CurrentCulture, и это значение сравнивается со значениями SelectListItem для предварительного выбора параметров списка.

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

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

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

Привет Рольф

person Rolf    schedule 14.06.2012