MVC Multiple DropDownLists aus 1 Liste

Hintergrund: Ich habe auf meiner Seite 4 Dropdown-Listen, von denen alle eine Liste von SelectListItem , um Daten SelectListItem . Alle 4 dieser Dropdowns enthalten immer dieselben Elemente. Jede Dropdown-Liste enthält oben ein leeres Element.

Problem: Wenn ich keinen Eintrag aus der Liste auswähle, der den 2. Platz darstellt, wird beim Laden der Seite die 2. Liste automatisch den Eintrag ausgewählt, der in der 1. Liste ausgewählt ist. Dies liegt daran, dass die Liste (glaube ich) ein SelectListItem wobei Selected = true , und es wird nur dieses in der zweiten Liste verwendet.

Gibt es eine Möglichkeit, eine Listenquelle für mehrere Dropdown-Listen zu verwenden? Ich möchte diese Liste nicht viermal kopieren, es sei denn, ich muss …

Code :

 //this is the list source public IEnumerable PossibleItems { get; set; } //this is the code on my .cshtml page @Html.DropDownListFor(x => x.SelectedItem1, Model.PossibleItems) @Html.DropDownListFor(x => x.SelectedItem2, Model.PossibleItems) @Html.DropDownListFor(x => x.SelectedItem3, Model.PossibleItems) @Html.DropDownListFor(x => x.SelectedItem4, Model.PossibleItems) 

    Vor 2 Jahren, aber für jeden, der das so findet, wie ich nach Antworten gesucht habe, ist der obige Kommentar von Feussy der richtige Weg. Ich werde versuchen zu erklären, warum und was ich gefunden habe.

    Verwenden Sie das OP-Beispiel oben. Um das beschriebene Verhalten zu sehen, müssen einige Bedingungen erfüllt sein.

    • x.SelectedItem1 sollte einen Wert haben (zB 1).
    • x.SelectedItem2 muss NULL sein. (Wenn es sich nicht um einen nullfähigen Typ handelt und nur ein INT angegeben wird, wird der Standardwert 0 und das Verhalten wird nicht angezeigt.)

    Setzen Sie einen Haltepunkt unter @Html.DropDownListFor(x => x.SelectedItem1, Model.PossibleItems)

    Wenn Sie in Model.PossibleItems nachsehen, wird die Liste wie erwartet angezeigt. Lassen Sie den Code mit der nächsten Zeile fortfahren. Wenn Sie sich nun Model.PossibleItems ansehen, werden Sie feststellen, dass Html.DropDownListFor Ihre Auswahlliste für das Model geändert hat, anstatt es einfach zu verwenden! Die Option für x.SelectedItem1 hat jetzt ein ‘ausgewähltes’ Attribut, nicht nur im HTML-Code, das an den Client gesendet wird, sondern auch in Ihrem Modell! Dies scheint ein schlechtes Verhalten bei Html.DropDownListFor zu sein, tut es aber definitiv.

    Wenn Sie nun @Html.DropDownListFor(x => x.SelectedItem2, Model.PossibleItems)

    • Wenn x.SelectedItem2 einen Wert hat, wird es gesetzt und Sie werden in Ordnung sein, aber ….
    • Wenn x.SelectedItem2 den Wert null hat, scheint die zweite @ Html.DropDownListFor die geänderte (von der ersten DropDownListFor) Auswahlliste so zu übernehmen, wie sie ist, und in der zweiten Dropdownliste wird x.SelectedItem1 ausgewählt. (weil die Auswahlliste selbst geändert wurde)

    Feussys Antwort funktioniert, weil anstatt einer selectList für das Modell, die wiederverwendet wird, separate selectLists erstellt werden, die aus einer List / IEnumerable für das Modell generiert werden, die stattdessen wiederverwendet wird.

    Die Moral der Geschichte ist also, eine selectList mit nullwertfähigen Werten nicht wiederzuverwenden, da Html.DropDownListFor keine Probleme beim Ändern der Sache hat und ausgewählte Attribute nicht löscht, wenn der Wert NULL ist.

    Hoffe das war klar.

    In Ihrer Liste müssen Sie für jede der vier Dropdown-Listen unterschiedliche SelectList-Entitäten erstellen:

     @Html.DropDownListFor(x => x.SelectedItem1, new SelectList(Model.PossibleItems, "dataValue", "textValue", Model.SelectedItem1)) @Html.DropDownListFor(x => x.SelectedItem2, Model.PossibleItems) new SelectList(Model.PossibleItems, "dataValue", "textValue", Model.SelectedItem2)) @Html.DropDownListFor(x => x.SelectedItem3, Model.PossibleItems) new SelectList(Model.PossibleItems, "dataValue", "textValue", Model.SelectedItem3)) @Html.DropDownListFor(x => x.SelectedItem4, Model.PossibleItems) new SelectList(Model.PossibleItems, "dataValue", "textValue", Model.SelectedItem4)) 

    In diesem Beispiel sind “dataValue” und “textValue” die Eigenschaften des SelectListItem-Objekts, die Ihrem Wert und Ihren Textelementen der Dropdown-Optionen entsprechen.

    Der Code, den Sie derzeit verwenden, ist der beste Weg, dies zu tun, und es sollte so funktionieren, wie es ist. SelectListItem hat eine Selected Eigenschaft, diese wird jedoch meistens von einer SelectList Instanz festgelegt. Andernfalls müssten Sie diese Eigenschaft irgendwo selbst festlegen. Da Sie IEnumerable anstelle einer instanziierten SelectList , sollten alle Elemente standardmäßig auf “false” gesetzt sein. Erst wenn Razor das DropDownListFor Steuerelement rendert, wird die DropDownListFor in eine tatsächliche SelectList und der ausgewählte Wert wird basierend auf dem Modell festgelegt. Überprüfen Sie Ihren anderen Code und stellen Sie sicher, dass Sie den ausgewählten Status nicht an irgendeiner Stelle manuell einstellen.

    FWIW, Sie müssen kein leeres Element manuell hinzufügen: Mit dem DropDownListFor Steuerelement können Sie der Liste ein leeres Element hinzufügen.

     @Html.DropDownListFor(x => x.SelectedItem1, Model.PossibleItems, string.Empty) 

    Verwenden Sie statt einer List eine SelectList . Dann können Sie die Liste der Elemente in DropDownListFor .

    Modell:

     public SelectList PossibleItems { get; set; } 

    Regler:

     var items = new List(); model.PossibleItems = new SelectList(items, "Value", "Text"); 

    Aussicht:

     @Html.DropDownListFor(m => m.Item1, Model.PossibleItems) @Html.DropDownListFor(m => m.Item2, Model.PossibleItems)