I rozwiązać ten problem przy użyciu metody rozszerzenie, dzięki czemu można napisać to w widokach:
@Html.DropDownListFor(x => x.SelectedSomething,
Model.Somethings.ToSelectList(n => n, v => v),
"Select an Option")
Dla int kolekcji może trzeba użyć n => n.ToString()
jako selektor nazwa.
Piękno tego podejścia polega na tym, że można go używać do dowolnego przelicznika. W twoim przykładzie (z listą liczb całkowitych), po prostu podajemy lambdas, które zwracają sam element, co spowoduje, że tekst i wartość zostaną ustawione na tę samą wartość na wyświetlonej liście opcji.
Jeśli chcesz uniknąć importowania przestrzeni nazw klasy rozszerzeń w pliku Web.config, zadeklaruj właściwość tylko do odczytu w swoim ViewModelu, który zwraca SelectList, a następnie uzyskaj dostęp do tego widoku.
Część Web.config wyglądałaby tak (zwróć uwagę, że musisz utworzyć linię zarówno dla złożenia, jak i dla obszaru nazw). Zauważ również, że twój folder Widoki zawiera oddzielny plik Web.config, który może przesłonić lub rozszerzyć definicje w głównym pliku Web.config.
<system.web>
<compilation debug="true" targetFramework="4.0" batch="true">
<assemblies>
<add assembly="My.Web.Stuff" />
</assemblies>
</compilation>
<pages>
<namespaces>
<add namespace="My.Web.Stuff.Extensions" />
</namespaces>
</pages>
</system.web>
Jest to realizacja dla metod rozszerzenie:
/// <summary>
/// Extension methods on IEnumerable.
/// </summary>
public static class SelectListExtensions
{
/// <summary>
/// Converts the source sequence into an IEnumerable of SelectListItem
/// </summary>
/// <param name = "items">Source sequence</param>
/// <param name = "nameSelector">Lambda that specifies the name for the SelectList items</param>
/// <param name = "valueSelector">Lambda that specifies the value for the SelectList items</param>
/// <returns>IEnumerable of SelectListItem</returns>
public static IEnumerable<SelectListItem> ToSelectList<TItem, TValue>(this IEnumerable<TItem> items, Func<TItem, TValue> valueSelector, Func<TItem, string> nameSelector)
{
return items.ToSelectList(valueSelector, nameSelector, x => false);
}
/// <summary>
/// Converts the source sequence into an IEnumerable of SelectListItem
/// </summary>
/// <param name = "items">Source sequence</param>
/// <param name = "nameSelector">Lambda that specifies the name for the SelectList items</param>
/// <param name = "valueSelector">Lambda that specifies the value for the SelectList items</param>
/// <param name = "selectedItems">Those items that should be selected</param>
/// <returns>IEnumerable of SelectListItem</returns>
public static IEnumerable<SelectListItem> ToSelectList<TItem, TValue>(this IEnumerable<TItem> items, Func<TItem, TValue> valueSelector, Func<TItem, string> nameSelector, IEnumerable<TValue> selectedItems)
{
return items.ToSelectList(valueSelector, nameSelector, x => selectedItems != null && selectedItems.Contains(valueSelector(x)));
}
/// <summary>
/// Converts the source sequence into an IEnumerable of SelectListItem
/// </summary>
/// <param name = "items">Source sequence</param>
/// <param name = "nameSelector">Lambda that specifies the name for the SelectList items</param>
/// <param name = "valueSelector">Lambda that specifies the value for the SelectList items</param>
/// <param name = "selectedValueSelector">Lambda that specifies whether the item should be selected</param>
/// <returns>IEnumerable of SelectListItem</returns>
public static IEnumerable<SelectListItem> ToSelectList<TItem, TValue>(this IEnumerable<TItem> items, Func<TItem, TValue> valueSelector, Func<TItem, string> nameSelector, Func<TItem, bool> selectedValueSelector)
{
return from item in items
let value = valueSelector(item)
select new SelectListItem
{
Text = nameSelector(item),
Value = value.ToString(),
Selected = selectedValueSelector(item)
};
}
}
mi się podoba. Użyję go jutro w pracy! Kod wygląda legalnie, oznaczając jako odpowiedź, dzięki! – Gromer