Próbowałem, to jest RC1, a następnie zaktualizowałem do RC2, co nie rozwiązało problemu.
// in my controller
ViewData["UserId"] = new SelectList(
users,
"UserId",
"DisplayName",
selectedUserId.Value); // this has a value
wynik: właściwość SelectedValue jest ustawiana w obiekcie
// in my view
<%=Html.DropDownList("UserId", (SelectList)ViewData["UserId"])%>
wynik: wszystkie oczekiwane opcje są renderowane dla klienta, ale wybrany atrybut nie jest ustawiony. Element w SelectedValue istnieje na liście, ale pierwsza pozycja na liście jest zawsze domyślnie zaznaczona.
Jak mam to robić?
Aktualizacja Dzięki odpowiedzi Johna Feminelli dowiedziałem się, na czym polega problem. „UserId” to właściwość w modelu, do którego jest silnie wpisany mój widok. Gdy Html.DropDownList („UserId” zostanie zmieniona na dowolną inną nazwę oprócz „UserId”, wybrana wartość jest wyświetlana poprawnie.
Powoduje to jednak, że wartość nie jest związana z modelem.
asp.net-mvc
blu
źródło
źródło
Odpowiedzi:
Oto jak naprawiłem ten problem:
Miałem:
Kontroler:
Widok
Zmienione przez:
Widok
Wygląda na to, że DropDown nie może mieć tej samej nazwy, ma nazwę ViewData: S dziwne, ale zadziałało.
źródło
Spróbuj tego:
I wtedy:
Dzięki MVC RC2 otrzymuję:
źródło
Nadal możesz nazwać DropDown jako „UserId” i nadal mieć powiązanie modelu działające poprawnie.
Jedynym wymaganiem, aby to zadziałało, jest to, że klucz ViewData zawierający SelectList nie ma takiej samej nazwy jak właściwość Model, którą chcesz powiązać. W twoim konkretnym przypadku byłoby to:
Spowoduje to utworzenie elementu select o nazwie UserId, który ma taką samą nazwę jak właściwość UserId w modelu, a zatem spinacz modelu ustawi go na wartość wybraną w elemencie selekcji HTML wygenerowanym przez pomocnika Html.DropDownList.
Nie jestem pewien, dlaczego ten konkretny konstruktor Html.DropDownList nie wybierze wartości określonej w SelectList po umieszczeniu listy wyboru w ViewData z kluczem równym nazwie właściwości. Podejrzewam, że ma to coś wspólnego ze sposobem, w jaki pomocnik DropDownList jest używany w innych scenariuszach, w których konwencja jest taka, że masz SelectList w ViewData o tej samej nazwie, co właściwość w Twoim modelu. To zadziała poprawnie:
źródło
Jeśli uważamy, że nie jest to błąd, który zespół powinien naprawić, przynajmniej MSDN powinno poprawić dokument. Zagmatwanie naprawdę pochodzi z kiepskiego dokumentu tego. W MSDN wyjaśnia nazwę parametrów jako,
Oznacza to po prostu, że ostateczny wygenerowany kod HTML będzie używał tego parametru jako nazwy wybranego wejścia. Ale to w rzeczywistości oznacza coś więcej.
Myślę, że projektant zakłada, że użytkownik użyje modelu widoku do wyświetlenia listy rozwijanej, a także użyje postu z powrotem do tego samego modelu widoku. Ale w wielu przypadkach tak naprawdę nie kierujemy się tym założeniem.
Skorzystaj z powyższego przykładu,
Jeśli będziemy postępować zgodnie z założeniem, powinniśmy zdefiniować model widoku dla tego widoku powiązanego z rozwijaną listą
Ponieważ podczas wysyłania zwrotnego tylko wybrana wartość zostanie odesłana, więc przyjmuje się, że powinna zostać wysłana z powrotem do właściwości modelu SelectedPersonId, co oznacza, że pierwsza nazwa parametru Html.DropDownList powinna mieć wartość „SelectedPersonId”. Dlatego projektant uważa, że podczas wyświetlania widoku modelu w widoku właściwość modelu SelectedPersonId powinna zawierać wartość domyślną tej listy rozwijanej. Nawet jeśli Twoja lista <SelectListItem> Persons już ustawiła flagę Selected, aby wskazać, która z nich jest wybrana / default, tml.DropDownList faktycznie zignoruje to i przebuduje swój własny IEnumerable <SelectListItem> i ustawi domyślny / wybrany element na podstawie nazwy.
Oto kod z asp.net mvc
Tak więc kod poszedł dalej, nie tylko spróbuje wyszukać nazwę w modelu, ale także w danych viewdata, gdy tylko je znajdzie, odbuduje selectList i zignoruje oryginalny Selected.
Problem w tym, że w wielu przypadkach tak naprawdę nie używamy tego w ten sposób. chcemy po prostu wrzucić selectList z jednym / wieloma elementami Selected set true.
Oczywiście rozwiązanie jest proste, użyj nazwy, której nie ma w modelu ani w viewdata. Jeśli nie może znaleźć dopasowania, użyje oryginalnej listy selectList, a oryginalny Selected będzie mieć wpływ.
Ale nadal uważam, że mvc powinno to poprawić, dodając jeszcze jeden warunek
Ponieważ jeśli oryginalna lista selectList miała już jedną Selected, dlaczego miałbyś to zignorować?
Tylko moje myśli.
źródło
Kod w poprzednim poście MVC 3 nie działa, ale to dobry początek. Naprawię to. Przetestowałem ten kod i działa w MVC 3 Razor C # Ten kod używa wzorca ViewModel do wypełnienia właściwości, która zwraca
List<SelectListItem>
.Klasa Model
Klasa ViewModel
Metoda kontrolera
Widok
Dane wyjściowe HTML będą podobne do
w zależności od tego, jak sformatujesz dane wyjściowe. Mam nadzieję, że to pomoże. Kod działa.
źródło
selected
opcji.Wygląda na to, że jest to błąd w klasie SelectExtensions, ponieważ sprawdza ona tylko ViewData, a nie model dla wybranego elementu. Tak więc sztuczka polega na skopiowaniu wybranego elementu z modelu do kolekcji ViewData pod nazwą właściwości.
Jest to zaczerpnięte z odpowiedzi, której udzieliłem na forach MVC, mam również pełniejszą odpowiedź w poście na blogu, który używa atrybutu DropDownList Kaziego ...
Biorąc pod uwagę model
i podstawowy model widoku
Następnie piszemy szablon edytora DropDownList w następujący sposób.
To zadziała również, jeśli zmienisz ArticleType w modelu widoku na SelectListItem, chociaż musisz zaimplementować konwerter typów zgodnie z blogiem Kazi i zarejestrować go, aby zmusić spinacz do traktowania tego jako prostego typu.
W Twoim kontrolerze mamy wtedy ...
źródło
Problem polega na tym, że dropboxy nie działają tak samo jak listboxy, przynajmniej tak, jak oczekuje projekt ASP.NET MVC2: Dropbox dopuszcza tylko zero lub jedną wartość, ponieważ listy mogą mieć wiele wartości. Tak więc, będąc ścisłym w HTML, ta wartość nie powinna znajdować się na liście opcji jako flaga „selected”, ale w samym wejściu.
Zobacz poniższy przykład:
Kombinacja ma wybraną opcję, ale ma również ustawiony atrybut wartości . Tak więc, jeśli chcesz, aby ASP.NET MVC2 renderował dropbox, a także miał wybraną określoną wartość (tj. Wartości domyślne itp.), Powinieneś nadać jej wartość w renderowaniu, na przykład:
źródło
W ASP.NET MVC 3 możesz po prostu dodać swoją listę do ViewData ...
... a następnie odwołaj się do tego po nazwie w widoku brzytwy ...
Nie musisz ręcznie „używać” listy w wywołaniu DropDownList. Robiąc to w ten sposób, również poprawnie ustaw dla mnie wybraną wartość.
Zrzeczenie się:
źródło
Udało mi się uzyskać pożądany efekt, ale przy nieco innym podejściu. Na liście rozwijanej użyłem modelu, a następnie odniosłem się do niego. Nie jestem pewien, czy tego właśnie szukałeś.
Model.Matters.FeeStructures w powyższym miejscu to mój identyfikator, który może być wartością przedmiotu, który należy wybrać.
źródło