/ / asp.net mvc 3 pre-select Html.DropDownListFor nie działa w nerd obiad - asp.net-mvc, asp.net-mvc-3, html.dropdownlistdo

asp.net mvc 3 pre-select Html.DropDownListFor nie pracuje w nerd obiad - asp.net-mvc, asp.net-mvc-3, html.dropdownlistdo

Nauka o listach rozwijanych, próbuję dodać stronę tworzenia RSVP dla nerddinnera jak w Blog Scotta Gu z Html.DropDownListFor wymienia dostępne kolacje.

Mogę dostać listę rozwijaną, ale janie mogę uzyskać listy rozwijanej, aby wstępnie wybrać wartość ("Sample Dinner 2"), którą chcę. Im przy użyciu initilizer do wysiewu kilka obiektów obiad w db. Baza danych jest sql ce 4 przy użyciu "pierwszego podejścia" kodu EF. Przepraszam, wiem, że jest to typowy problem i nienawidzę go pytać, ale szczerze mówiąc spędziłem trochę czasu nad tym, ale nie mogę go uruchomić:

ViewModel

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

Kontroler

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

Widok

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

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

Tak więc nie jest preselekcja listy rozwijanej o wartości "Sample Dinner 2" podczas ładowania strony. Lista wyświetla ok i ustawia prawidłowy DinnerID po dokonaniu wyboru i kliknięciu przycisku Prześlij.

Próbuje to również:

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

ale nie ustawia ani nie łączy z Rsvp.DinnerID.

Ta opcja wybiera z listy, ale nie wiąże (ani nie ustawia Rsvp.DinnerID)

@Html.DropDownList("DinnersList")

Chcę zachować go z mvc3, więc chcę go wdrożyćsilny typ przy użyciu podejścia ViewModel (bez ViewData) i najlepiej przy użyciu Html.DropDownListFor (nie Html.DropDownList) .Viewbag wydaje się niepotrzebne w tym przypadku.

Dzięki!

Edytuj1

Myślenie, że powinienem używać selectList z selectListItems Próbowałem to verbose podejście:

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

Jednak wciąż nie ma pracy. Czy powinienem używać właściwości ViewModel SelectedItem w: @ Html.DropDownListFor .. jakoś? Coś jak :

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

ale jak uzyskać wybraną wartość, aby ustawić Rsvp.DinnerID. Myślę, że to nazywało się bindowaniem.

Odpowiedzi:

12 dla odpowiedzi № 1

Po przeczytaniu tutaj i tutaj, W końcu rozumiem, w jaki sposób HtmlDropDownlistFor automatycznie wybiera odpowiedni element z menu rozwijanego w oparciu o twój model - wybranie parametru dinnerID w RSVP (klucz obcy na obiad.dinnerID) spowoduje, że menu zawiera listę Dinner.DinnerIDs, aby wstępnie wybrać tę wartość. Nie ma potrzeby jeszcze Myślę dla selectedValue w SelectList lub ViewModel.

Rozwiązanie:

    //
//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 dla odpowiedzi № 2

The SelectList konstruktor którego używasz ma dostarczyć wybranej wartości, ale podajesz wybrany tekst. Możesz spróbować:

    int selected = 2;

2 dla odpowiedzi nr 3

Html.DropDownList działa tylko wtedy, gdy właściwość bound jest int. Każdy inny typ, taki jak nazwany wylicznik, spowoduje, że domyślnie zostanie ustawiony pierwszy element.

Dodaj właściwość do swojego modelu, wpisz int, która otacza enum, które próbujesz zachować:

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

Nie musisz używać Selected w SelectList - Html.DropDownList będzie synchronizować dobrze.


2 dla odpowiedzi № 4

Proszę uważać, jeśli jest QUERY STRING z Takie samo imię , zastąpi to zachowanie, Nie wiem o UKRYTYCH POLACH o tej samej nazwie.

Na przykład.

DropDownListFor użyje wartości Ciąg zapytania z DinnerID, jeśli uznany


1 dla odpowiedzi nr 5

Html.DropDownList akceptuje właściwości int, DropDownListFor też, ale musisz być ostrożny, co robisz. Zbadałem plik SelectExtensions.cs z ASP.NET MVC 3 i znalazłem to:

Kiedy używasz DropDownList ("XyField", "default"), aby utworzyć DropDown, musisz umieścić listę wyboru w ViewBag.XyField i DropDownList () obsługuje to poprawnie.

Kiedy używasz DropDownListFor (m => m.XyField, ...), możesz przekazać listę select explictly, jak poniżej: DropDownListFor (m => m.XyField, ViewBag.XyFieldList jak IEnumerable)

Gdy to zrobisz, następujące czynności:

  • Drugi parametr DropDownListFor (...) zostanie użyty jako źródło dla opcji
  • Jeśli istnieje pozycja ModelState dla "XyField", zostanie ona użyta jako wartość modelu
  • Jeśli nie ma stanu modelu ORAZ Html.ViewData.Eval ("XyField") zwraca wartość nie null, ta wartość będzie używana jako wartość modelu.
  • Jeśli znaleziona wartość modelu nie jest pusta, zostanie przekonwertowana na ciąg znaków przy użyciu właściwości CultureInfo.CurrentCulture, a wartość ta zostanie porównana z wartościami SelectListItem, aby wstępnie wybrać opcje listy.

Uwaga: jeśli zapisałeś listę wyboru w ViewBag.XyField, zostanie ona znaleziona przed uzyskaniem dostępu do modelu. Nie chcesz porównywać "selectList.ToString ()" z "selectList [i] .Value", aby wstępnie wybrać opcje. Zapisz listę wyboru w innym miejscu!

Zabawne jest to, że możesz użyć DropDownListForz niejawną listą wyboru, w taki sam sposób, jak tego oczekujesz od DropDownList (). W takim przypadku możesz nawet zapisać swoją listę w ViewBag.XyField. Aby to zadziałało, musisz po prostu wywołać pomocnika z pustym jako drugim parametrem: DropDownListFor (m => m.XyField, zero)

Następnie lista wyboru jest pobierana z ViewBag.XyField i krok 3 na powyższej liście są pomijane. Tak więc, jeśli XyField jest w stanie modelu, będzie to miało pierwszeństwo przed własnymi wybranymi właściwościami na liście wyboru, ale poza tym lista wyboru będzie używana "tak jak jest".

Pozdrowienia Rolf