Jak utworzyć dropdownlist z enum w ASP.NET MVC?
Próbuję użyć metody rozszerzenia Html.DropDownList
, ale nie mogę rozgryźć, jak jej użyć przy wyliczaniu.
Powiedzmy, że mam takie Wyliczenie:
public enum ItemTypes
{
Movie = 1,
Game = 2,
Book = 3
}
Jak utworzyć listę rozwijaną z tymi wartościami przy użyciu metody rozszerzenia Html.DropDownList
?
A może najlepiej utworzyć pętlę for i ręcznie utworzyć elementy Html?
30 answers
Dla MVC v5.1 Użyj Html.EnumDropDownListFor
@Html.EnumDropDownListFor(
x => x.YourEnumField,
"Select My Type",
new { @class = "form-control" })
Dla MVC v5 użyj EnumHelper
@Html.DropDownList("MyType",
EnumHelper.GetSelectList(typeof(MyType)) ,
"Select My Type",
new { @class = "form-control" })
Dla MVC 5 i niższych
Zwinąłem odpowiedź Rune ' a do metody rozszerzenia:
namespace MyApp.Common
{
public static class MyExtensions{
public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
where TEnum : struct, IComparable, IFormattable, IConvertible
{
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { Id = e, Name = e.ToString() };
return new SelectList(values, "Id", "Name", enumObj);
}
}
}
To pozwala napisać:
ViewData["taskStatus"] = task.Status.ToSelectList();
By using MyApp.Common
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-26 02:22:20
Wiem, że jestem spóźniony na przyjęcie w tej sprawie, ale pomyślałem, że ten wariant może okazać się przydatny, ponieważ ten pozwala również używać ciągów opisowych zamiast stałych wyliczeń w rozwijanej liście. Aby to zrobić, udekoruj każdy wpis wyliczenia znakiem [System.ComponentModel.Opis] atrybut.
Na przykład:
public enum TestEnum
{
[Description("Full test")]
FullTest,
[Description("Incomplete or partial test")]
PartialTest,
[Description("No test performed")]
None
}
Oto Mój kod:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Reflection;
using System.ComponentModel;
using System.Linq.Expressions;
...
private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
{
Type realModelType = modelMetadata.ModelType;
Type underlyingType = Nullable.GetUnderlyingType(realModelType);
if (underlyingType != null)
{
realModelType = underlyingType;
}
return realModelType;
}
private static readonly SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = "", Value = "" } };
public static string GetEnumDescription<TEnum>(TEnum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if ((attributes != null) && (attributes.Length > 0))
return attributes[0].Description;
else
return value.ToString();
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
{
return EnumDropDownListFor(htmlHelper, expression, null);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes)
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Type enumType = GetNonNullableModelType(metadata);
IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();
IEnumerable<SelectListItem> items = from value in values
select new SelectListItem
{
Text = GetEnumDescription(value),
Value = value.ToString(),
Selected = value.Equals(metadata.Model)
};
// If the enum is nullable, add an 'empty' item to the collection
if (metadata.IsNullableValueType)
items = SingleEmptyItem.Concat(items);
return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
}
Możesz to zrobić według Ciebie:
@Html.EnumDropDownListFor(model => model.MyEnumProperty)
Mam nadzieję, że to ci pomoże!
**EDIT 2014-JAN-23: Microsoft mają właśnie ukazał się MVC 5.1, który ma teraz funkcję EnumDropDownListFor. Niestety wydaje się, że nie respektuje atrybutu [Description], więc powyższy kod nadal stoi.Zobacz sekcję Enum w Uwagach do wydania Microsoft dla MVC 5.1.
Aktualizacja: obsługuje atrybut Display [Display(Name = "Sample")]
, więc można go używać.
[Update - właśnie to zauważyłem, a kod wygląda jak rozszerzona wersja kodu tutaj: https://blogs.msdn.microsoft.com/stuartleeks/2010/05/21/asp-net-mvc-creating-a-dropdownlist-helper-for-enums/, z kilkoma dodatkami. Jeśli tak, to przypisanie wydaje się sprawiedliwe; -)]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-18 09:43:37
In ASP.NET MVC 5.1, dodali helpera EnumDropDownListFor()
, więc nie ma potrzeby tworzenia własnych rozszerzeń:
Model :
public enum MyEnum
{
[Display(Name = "First Value - desc..")]
FirstValue,
[Display(Name = "Second Value - desc...")]
SecondValue
}
widok :
@Html.EnumDropDownListFor(model => model.MyEnum)
Using Tag Helper (ASP.NET MVC 6):
<select asp-for="@Model.SelectedValue" asp-items="Html.GetEnumSelectList<MyEnum>()">
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-18 09:44:20
Wpadłem na ten sam problem, znalazłem to pytanie i pomyślałem, że rozwiązanie dostarczone przez Ash nie jest tym, czego szukałem; samodzielne tworzenie HTML oznacza mniejszą elastyczność w porównaniu do wbudowanej funkcji Html.DropDownList()
.
Okazuje się, że C # 3 itd. to ułatwia sprawę. Mam enum
o nazwie TaskStatus
:
var statuses = from TaskStatus s in Enum.GetValues(typeof(TaskStatus))
select new { ID = s, Name = s.ToString() };
ViewData["taskStatus"] = new SelectList(statuses, "ID", "Name", task.Status);
To tworzy dobry ol ' SelectList
, który może być używany jak jesteś przyzwyczajony do w widoku:
<td><b>Status:</b></td><td><%=Html.DropDownList("taskStatus")%></td></tr>
Anonimowy typ i LINQ sprawia, że jest to o wiele bardziej eleganckie IMHO. Bez obrazy, Ash. :)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-29 04:44:18
Tutaj jest lepsze rozwiązanie:
Https://www.spicelogic.com/Blog/enum-dropdownlistfor-asp-net-mvc-5
Powiedz, że oto twój model:
Przykładowe Użycie:
Generowany interfejs użytkownika:
I wygenerowany HTML
Kod źródłowy rozszerzenia pomocniczego snap shot:
Możesz pobrać przykładowy projekt z linku I pod warunkiem.
EDIT: Oto kod:
public static class EnumEditorHtmlHelper
{
/// <summary>
/// Creates the DropDown List (HTML Select Element) from LINQ
/// Expression where the expression returns an Enum type.
/// </summary>
/// <typeparam name="TModel">The type of the model.</typeparam>
/// <typeparam name="TProperty">The type of the property.</typeparam>
/// <param name="htmlHelper">The HTML helper.</param>
/// <param name="expression">The expression.</param>
/// <returns></returns>
public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression)
where TModel : class
{
TProperty value = htmlHelper.ViewData.Model == null
? default(TProperty)
: expression.Compile()(htmlHelper.ViewData.Model);
string selected = value == null ? String.Empty : value.ToString();
return htmlHelper.DropDownListFor(expression, createSelectList(expression.ReturnType, selected));
}
/// <summary>
/// Creates the select list.
/// </summary>
/// <param name="enumType">Type of the enum.</param>
/// <param name="selectedItem">The selected item.</param>
/// <returns></returns>
private static IEnumerable<SelectListItem> createSelectList(Type enumType, string selectedItem)
{
return (from object item in Enum.GetValues(enumType)
let fi = enumType.GetField(item.ToString())
let attribute = fi.GetCustomAttributes(typeof (DescriptionAttribute), true).FirstOrDefault()
let title = attribute == null ? item.ToString() : ((DescriptionAttribute) attribute).Description
select new SelectListItem
{
Value = item.ToString(),
Text = title,
Selected = selectedItem == item.ToString()
}).ToList();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-18 09:49:09
Html.DropDownListFor wymaga tylko liczby, więc alternatywą dla rozwiązania Prise jest następujący. To pozwoli Ci po prostu napisać:
@Html.DropDownListFor(m => m.SelectedItemType, Model.SelectedItemType.ToSelectList())
[Gdzie SelectedItemType jest polem w modelu typu ItemTypes, a model nie jest null]
Poza tym, nie musisz generować metody rozszerzenia, ponieważ możesz użyć wartości enumValue.GetType () zamiast typeof (T).
EDIT: zintegrowane rozwiązanie Simona również tutaj i zawiera rozszerzenie opisów metoda.
public static class EnumExtensions
{
public static IEnumerable<SelectListItem> ToSelectList(this Enum enumValue)
{
return from Enum e in Enum.GetValues(enumValue.GetType())
select new SelectListItem
{
Selected = e.Equals(enumValue),
Text = e.ToDescription(),
Value = e.ToString()
};
}
public static string ToDescription(this Enum value)
{
var attributes = (DescriptionAttribute[])value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-26 09:42:36
Więc bez funkcji rozszerzenia, Jeśli szukasz prostego i łatwego.. This is what I did
<%= Html.DropDownListFor(x => x.CurrentAddress.State, new SelectList(Enum.GetValues(typeof(XXXXX.Sites.YYYY.Models.State))))%>
Gdzie XXXXX.Miejsca.YYYY.Modelki.Stan jest enum
Prawdopodobnie lepiej wykonać funkcję pomocnika, ale gdy czas jest krótki, zadanie zostanie wykonane.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-26 17:13:06
Rozszerzając odpowiedzi Prise i Rune, jeśli chcesz, aby atrybut value wybranych elementów listy mapował wartość całkowitą typu wyliczenia, zamiast wartości łańcuchowej, użyj następującego kodu:
public static SelectList ToSelectList<T, TU>(T enumObj)
where T : struct
where TU : struct
{
if(!typeof(T).IsEnum) throw new ArgumentException("Enum is required.", "enumObj");
var values = from T e in Enum.GetValues(typeof(T))
select new {
Value = (TU)Convert.ChangeType(e, typeof(TU)),
Text = e.ToString()
};
return new SelectList(values, "Value", "Text", enumObj);
}
Zamiast traktować każdą wartość wyliczenia jako obiekt TEnum, możemy traktować ją jako obiekt, a następnie wrzucić ją do liczby całkowitej, aby uzyskać wartość nieobsługiwaną.
Uwaga: Dodałem również ogólne ograniczenie typu, aby ograniczyć typy, dla których to rozszerzenie jest dostępne tylko dla struktur (typ bazowy Enum) oraz Walidacja typu run-time, która zapewnia, że przekazywana struktura jest rzeczywiście Enum.
Aktualizacja 10/23/12: Dodano parametr generic type dla bazowego typu i naprawiono problem bez kompilacji wpływający na. Net 4+.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-23 16:04:59
Aby rozwiązać problem uzyskania numeru zamiast tekstu za pomocą metody rozszerzenia Prise.
public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
{
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString())
, Name = e.ToString() };
return new SelectList(values, "Id", "Name", enumObj);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-02 21:48:03
Super łatwy sposób, aby to zrobić - bez tych wszystkich rozszerzeń, które wydają się przesadne, jest to:
Twoje enum:
public enum SelectedLevel
{
Level1,
Level2,
Level3,
Level4
}
Wewnątrz kontrolera połącz Enum z listą:
List<SelectedLevel> myLevels = Enum.GetValues(typeof(SelectedLevel)).Cast<SelectedLevel>().ToList();
Potem wrzuć to do worka widokowego:
ViewBag.RequiredLevel = new SelectList(myLevels);
W końcu po prostu połącz go z widokiem:
@Html.DropDownList("selectedLevel", (SelectList)ViewBag.RequiredLevel, new { @class = "form-control" })
jest to zdecydowanie najprostszy sposób, jaki znalazłem i nie wymaga żadnych rozszerzeń ani niczego tak szalonego.
UPDATE : Zobacz komentarz poniżej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-29 22:28:07
Najlepszym rozwiązaniem było połączenie tego bloga z odpowiedzi Simona Goldstone ' a.
Pozwala to na użycie enum w modelu. Zasadniczo chodzi o to, aby użyć właściwości integer, jak również enum i emulować właściwość integer.
Następnie użyj [System.ComponentModel.Opis] atrybut do dodawania adnotacji do modelu za pomocą wyświetlanego tekstu i używania rozszerzenia "EnumDropDownListFor"w widoku.
To sprawia, że zarówno Widok, jak i model bardzo czytelny i łatwy w utrzymaniu.
Model:
public enum YesPartialNoEnum
{
[Description("Yes")]
Yes,
[Description("Still undecided")]
Partial,
[Description("No")]
No
}
//........
[Display(Name = "The label for my dropdown list")]
public virtual Nullable<YesPartialNoEnum> CuriousQuestion{ get; set; }
public virtual Nullable<int> CuriousQuestionId
{
get { return (Nullable<int>)CuriousQuestion; }
set { CuriousQuestion = (Nullable<YesPartialNoEnum>)value; }
}
Widok:
@using MyProject.Extensions
{
//...
@Html.EnumDropDownListFor(model => model.CuriousQuestion)
//...
}
Rozszerzenie (bezpośrednio z odpowiedzi Simona Goldstone ' a , dołączonej tutaj dla kompletności):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.ComponentModel;
using System.Reflection;
using System.Linq.Expressions;
using System.Web.Mvc.Html;
namespace MyProject.Extensions
{
//Extension methods must be defined in a static class
public static class MvcExtensions
{
private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
{
Type realModelType = modelMetadata.ModelType;
Type underlyingType = Nullable.GetUnderlyingType(realModelType);
if (underlyingType != null)
{
realModelType = underlyingType;
}
return realModelType;
}
private static readonly SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = "", Value = "" } };
public static string GetEnumDescription<TEnum>(TEnum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if ((attributes != null) && (attributes.Length > 0))
return attributes[0].Description;
else
return value.ToString();
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
{
return EnumDropDownListFor(htmlHelper, expression, null);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes)
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Type enumType = GetNonNullableModelType(metadata);
IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();
IEnumerable<SelectListItem> items = from value in values
select new SelectListItem
{
Text = GetEnumDescription(value),
Value = value.ToString(),
Selected = value.Equals(metadata.Model)
};
// If the enum is nullable, add an 'empty' item to the collection
if (metadata.IsNullableValueType)
items = SingleEmptyItem.Concat(items);
return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-18 09:50:05
Chcesz spojrzeć na używając czegoś takiego jak Enum.GetValues
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-18 09:50:42
@Html.DropDownListFor(model => model.Type, Enum.GetNames(typeof(Rewards.Models.PropertyType)).Select(e => new SelectListItem { Text = e }))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-24 00:53:33
To jest Rune & Prise odpowiedzi zmienione tak, aby używać wartości Enum int
jako ID.
Przykładowe Wyliczenie:
public enum ItemTypes
{
Movie = 1,
Game = 2,
Book = 3
}
Metoda rozszerzenia:
public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
{
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { Id = (int)Enum.Parse(typeof(TEnum), e.ToString()), Name = e.ToString() };
return new SelectList(values, "Id", "Name", (int)Enum.Parse(typeof(TEnum), enumObj.ToString()));
}
Próbka użycia:
<%= Html.DropDownList("MyEnumList", ItemTypes.Game.ToSelectList()) %>
Pamiętaj, aby zaimportować przestrzeń nazw zawierającą metodę rozszerzenia
<%@ Import Namespace="MyNamespace.LocationOfExtensionMethod" %>
Przykład wygenerowanego HTML:
<select id="MyEnumList" name="MyEnumList">
<option value="1">Movie</option>
<option selected="selected" value="2">Game</option>
<option value="3">Book </option>
</select>
Zauważ, że element, którego używasz do wywołania ToSelectList
on, jest wybranym elementem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-01 12:23:03
To jest wersja dla Razor:
@{
var itemTypesList = new List<SelectListItem>();
itemTypesList.AddRange(Enum.GetValues(typeof(ItemTypes)).Cast<ItemTypes>().Select(
(item, index) => new SelectListItem
{
Text = item.ToString(),
Value = (index).ToString(),
Selected = Model.ItemTypeId == index
}).ToList());
}
@Html.DropDownList("ItemTypeId", itemTypesList)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-12 06:52:12
Teraz ta funkcja jest obsługiwana od zaraz w MVC 5.1 do @Html.EnumDropDownListFor()
Sprawdź poniższy link:
Https://docs.microsoft.com/en-us/aspnet/mvc/overview/releases/mvc51-release-notes#Enum
To naprawdę wstyd, że zajęło Microsoftowi 5 lat, aby zaimplementować takie funkcje, które są tak pożądane zgodnie z powyższym głosowaniem!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-18 09:51:12
Bazując na odpowiedzi Simona, podobnym podejściem jest wyświetlanie wartości Enum z pliku zasobu, zamiast w atrybucie opisu wewnątrz samego Enum. Jest to pomocne, jeśli Twoja witryna musi być renderowana w więcej niż jednym języku i jeśli chcesz mieć konkretny plik zasobów dla Enum, możesz pójść o krok dalej i mieć tylko wartości Enum, w swoim Enum i odwoływać się do nich z rozszerzenia za pomocą konwencji takiej jak [EnumName]_[EnumValue] - ostatecznie mniej pisanie!
Rozszerzenie wygląda wtedy następująco:
public static IHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> html, Expression<Func<TModel, TEnum>> expression)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var enumType = Nullable.GetUnderlyingType(metadata.ModelType) ?? metadata.ModelType;
var enumValues = Enum.GetValues(enumType).Cast<object>();
var items = from enumValue in enumValues
select new SelectListItem
{
Text = GetResourceValueForEnumValue(enumValue),
Value = ((int)enumValue).ToString(),
Selected = enumValue.Equals(metadata.Model)
};
return html.DropDownListFor(expression, items, string.Empty, null);
}
private static string GetResourceValueForEnumValue<TEnum>(TEnum enumValue)
{
var key = string.Format("{0}_{1}", enumValue.GetType().Name, enumValue);
return Enums.ResourceManager.GetString(key) ?? enumValue.ToString();
}
Zasoby w Enumach.Plik Resx wygląda jak ItemTypes_Movie: Film
Inną rzeczą, którą lubię robić, jest to, że zamiast wywoływać metodę rozszerzenia bezpośrednio, wolałbym wywołać ją za pomocą @Html.EditorFor (x => x. MyProperty), lub najlepiej po prostu mieć cały formularz, w jednym schludnym @Html.EditorForModel (). Aby to zrobić zmieniam szablon string, aby wyglądał tak
@using MVCProject.Extensions
@{
var type = Nullable.GetUnderlyingType(ViewData.ModelMetadata.ModelType) ?? ViewData.ModelMetadata.ModelType;
@(typeof (Enum).IsAssignableFrom(type) ? Html.EnumDropDownListFor(x => x) : Html.TextBoxFor(x => x))
}
Jeśli cię to interesuje, umieściłem o wiele bardziej szczegółowe odpowiedz tutaj na moim blogu:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-24 19:52:16
Cóż, jestem naprawdę spóźniony na imprezę, ale jeśli to coś warte, napisałem na blogu o tym właśnie temacie, w którym tworzę EnumHelper
klasę, która umożliwia bardzo łatwą transformację.
Http://jnye.co/Posts/4/creating-a-dropdown-list-from-an-enum-in-mvc-and-c%23
W Twoim kontrolerze:
//If you don't have an enum value use the type
ViewBag.DropDownList = EnumHelper.SelectListFor<MyEnum>();
//If you do have an enum value use the value (the value will be marked as selected)
ViewBag.DropDownList = EnumHelper.SelectListFor(MyEnum.MyEnumValue);
Według ciebie:
@Html.DropDownList("DropDownList")
@* OR *@
@Html.DropDownListFor(m => m.Property, ViewBag.DropDownList as SelectList, null)
Klasa pomocnicza:
public static class EnumHelper
{
// Get the value of the description attribute if the
// enum has one, otherwise use the value.
public static string GetDescription<TEnum>(this TEnum value)
{
var fi = value.GetType().GetField(value.ToString());
if (fi != null)
{
var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
{
return attributes[0].Description;
}
}
return value.ToString();
}
/// <summary>
/// Build a select list for an enum
/// </summary>
public static SelectList SelectListFor<T>() where T : struct
{
Type t = typeof(T);
return !t.IsEnum ? null
: new SelectList(BuildSelectListItems(t), "Value", "Text");
}
/// <summary>
/// Build a select list for an enum with a particular value selected
/// </summary>
public static SelectList SelectListFor<T>(T selected) where T : struct
{
Type t = typeof(T);
return !t.IsEnum ? null
: new SelectList(BuildSelectListItems(t), "Text", "Value", selected.ToString());
}
private static IEnumerable<SelectListItem> BuildSelectListItems(Type t)
{
return Enum.GetValues(t)
.Cast<Enum>()
.Select(e => new SelectListItem { Value = e.ToString(), Text = e.GetDescription() });
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-08 12:44:00
Jestem bardzo spóźniony, ale znalazłem naprawdę fajny sposób, aby to zrobić z jedną linijką kodu, jeśli jesteś szczęśliwy, aby dodać Unstrained Melody pakiet NuGet (ładna, mała biblioteka od Jona Skeeta).
To rozwiązanie jest lepsze ponieważ:
- zapewnia (z ograniczeniami typu ogólnego), że wartość rzeczywiście jest wartością enum (ze względu na nieograniczoną melodię)
- unika niepotrzebnego boksu (ze względu na nieskrępowaną melodię)
- buforuje wszystkie opisy aby uniknąć używania refleksji przy każdym wywołaniu (ze względu na nieskrępowaną melodię)
- to mniej kodu niż inne rozwiązania!
Oto kroki, aby to zadziałało:
- W Konsoli Menedżera Pakietów, "Install-Package Unstrained"
-
Dodaj nieruchomość na swoim modelu w ten sposób:
//Replace "YourEnum" with the type of your enum public IEnumerable<SelectListItem> AllItems { get { return Enums.GetValues<YourEnum>().Select(enumValue => new SelectListItem { Value = enumValue.ToString(), Text = enumValue.GetDescription() }); } }
Teraz, gdy masz listę SelectListItem na swoim modelu, możesz użyć @Html.DropDownList lub @ Html.Dropdownlistdla korzystania z tej właściwości jako źródło.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-18 09:51:54
Kolejna poprawka do tej metody rozszerzenia - bieżąca wersja nie wybrała bieżącej wartości enum. Poprawiłem ostatnią linijkę:
public static SelectList ToSelectList<TEnum>(this TEnum enumObj) where TEnum : struct
{
if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new
{
ID = (int)Enum.Parse(typeof(TEnum), e.ToString()),
Name = e.ToString()
};
return new SelectList(values, "ID", "Name", ((int)Enum.Parse(typeof(TEnum), enumObj.ToString())).ToString());
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-10 01:27:31
Jeśli chcesz dodać obsługę lokalizacji po prostu zmień metodę s.toString () na coś takiego:
ResourceManager rManager = new ResourceManager(typeof(Resources));
var dayTypes = from OperatorCalendarDay.OperatorDayType s in Enum.GetValues(typeof(OperatorCalendarDay.OperatorDayType))
select new { ID = s, Name = rManager.GetString(s.ToString()) };
Tutaj typeof (Resources) jest zasobem, który chcesz załadować, a następnie otrzymasz zlokalizowany ciąg znaków, również przydatny, jeśli twój enumerator ma wartości z wieloma słowami.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-12 12:09:18
To jest moja wersja metody helper. Używam tego:
var values = from int e in Enum.GetValues(typeof(TEnum))
select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) };
Zamiast tego:
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString())
, Name = e.ToString() };
Oto jest:
public static SelectList ToSelectList<TEnum>(this TEnum self) where TEnum : struct
{
if (!typeof(TEnum).IsEnum)
{
throw new ArgumentException("self must be enum", "self");
}
Type t = typeof(TEnum);
var values = from int e in Enum.GetValues(typeof(TEnum))
select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) };
return new SelectList(values, "ID", "Name", self);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-07 11:07:10
Możesz również użyć my custom HtmlHelpers w Griffin.MvcContrib. Następujący kod:
@Html2.CheckBoxesFor(model => model.InputType) <br />
@Html2.RadioButtonsFor(model => model.InputType) <br />
@Html2.DropdownFor(model => model.InputType) <br />
Generuje:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-28 08:29:48
Znalazłem odpowiedź TUTAJ . Jednak niektóre moje liczby mają atrybut [Description(...)]
, więc zmodyfikowałem kod, aby zapewnić wsparcie dla tego:
enum Abc
{
[Description("Cba")]
Abc,
Def
}
public static MvcHtmlString EnumDropDownList<TEnum>(this HtmlHelper htmlHelper, string name, TEnum selectedValue)
{
IEnumerable<TEnum> values = Enum.GetValues(typeof(TEnum))
.Cast<TEnum>();
List<SelectListItem> items = new List<SelectListItem>();
foreach (var value in values)
{
string text = value.ToString();
var member = typeof(TEnum).GetMember(value.ToString());
if (member.Count() > 0)
{
var customAttributes = member[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (customAttributes.Count() > 0)
{
text = ((DescriptionAttribute)customAttributes[0]).Description;
}
}
items.Add(new SelectListItem
{
Text = text,
Value = value.ToString(),
Selected = (value.Equals(selectedValue))
});
}
return htmlHelper.DropDownList(
name,
items
);
}
Mam nadzieję, że to pomoże.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-18 09:53:20
@Simon Goldstone: dzięki za rozwiązanie, w moim przypadku można je idealnie zastosować. Jedynym problemem jest to, że musiałem przetłumaczyć to na VB. Ale teraz jest zrobione i aby zaoszczędzić czas innych ludzi (w razie potrzeby) umieściłem go tutaj:
Imports System.Runtime.CompilerServices
Imports System.ComponentModel
Imports System.Linq.Expressions
Public Module HtmlHelpers
Private Function GetNonNullableModelType(modelMetadata As ModelMetadata) As Type
Dim realModelType = modelMetadata.ModelType
Dim underlyingType = Nullable.GetUnderlyingType(realModelType)
If Not underlyingType Is Nothing Then
realModelType = underlyingType
End If
Return realModelType
End Function
Private ReadOnly SingleEmptyItem() As SelectListItem = {New SelectListItem() With {.Text = "", .Value = ""}}
Private Function GetEnumDescription(Of TEnum)(value As TEnum) As String
Dim fi = value.GetType().GetField(value.ToString())
Dim attributes = DirectCast(fi.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
If Not attributes Is Nothing AndAlso attributes.Length > 0 Then
Return attributes(0).Description
Else
Return value.ToString()
End If
End Function
<Extension()>
Public Function EnumDropDownListFor(Of TModel, TEnum)(ByVal htmlHelper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TEnum))) As MvcHtmlString
Return EnumDropDownListFor(htmlHelper, expression, Nothing)
End Function
<Extension()>
Public Function EnumDropDownListFor(Of TModel, TEnum)(ByVal htmlHelper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TEnum)), htmlAttributes As Object) As MvcHtmlString
Dim metaData As ModelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData)
Dim enumType As Type = GetNonNullableModelType(metaData)
Dim values As IEnumerable(Of TEnum) = [Enum].GetValues(enumType).Cast(Of TEnum)()
Dim items As IEnumerable(Of SelectListItem) = From value In values
Select New SelectListItem With
{
.Text = GetEnumDescription(value),
.Value = value.ToString(),
.Selected = value.Equals(metaData.Model)
}
' If the enum is nullable, add an 'empty' item to the collection
If metaData.IsNullableValueType Then
items = SingleEmptyItem.Concat(items)
End If
Return htmlHelper.DropDownListFor(expression, items, htmlAttributes)
End Function
End Module
Koniec używaj go tak:
@Html.EnumDropDownListFor(Function(model) (model.EnumField))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-28 08:21:09
Skończyło się na stworzeniu metod rozszerzania, aby zrobić to, co jest zasadniczo Akceptuj odpowiedź tutaj. Ostatnia połowa Gist dotyczy konkretnie Enum.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-01 19:14:51
@Html.DropdownListFor(model=model->Gender,new List<SelectListItem>
{
new ListItem{Text="Male",Value="Male"},
new ListItem{Text="Female",Value="Female"},
new ListItem{Text="--- Select -----",Value="-----Select ----"}
}
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-30 10:10:44
@Html.DropDownListFor(model => model.MaritalStatus, new List<SelectListItem>
{
new SelectListItem { Text = "----Select----", Value = "-1" },
new SelectListItem { Text = "Marrid", Value = "M" },
new SelectListItem { Text = "Single", Value = "S" }
})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-23 09:57:03
Oto odmiana Martina Faartofta, w której można umieścić niestandardowe etykiety, które są miłe dla lokalizacji.
public static class EnumHtmlHelper
{
public static SelectList ToSelectList<TEnum>(this TEnum enumObj, Dictionary<int, string> customLabels)
where TEnum : struct, IComparable, IFormattable, IConvertible
{
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { Id = e, Name = customLabels.First(x => x.Key == Convert.ToInt32(e)).Value.ToString() };
return new SelectList(values, "Id", "Name", enumObj);
}
}
Użycie w widoku:
@Html.DropDownListFor(m => m.Category, Model.Category.ToSelectList(new Dictionary<int, string>() {
{ 1, ContactResStrings.FeedbackCategory },
{ 2, ContactResStrings.ComplainCategory },
{ 3, ContactResStrings.CommentCategory },
{ 4, ContactResStrings.OtherCategory }
}), new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Category)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-13 19:00:53
Zrobiłem następujące i działa pomyślnie:
- w widoku.cshtml:
@model MyModel.cs
@Html.EnumDropDownListFor(m=>m.MyItemType )
- w modelu: MyModel.cs
public ItemTypes MyItemType { get; set; }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-13 17:50:16