Подтвердить что ты не робот

Как получить значения перечисления в SelectList

Представьте, что у меня есть перечисление, подобное этому (как пример):

public enum Direction{
    Horizontal = 0,
    Vertical = 1,
    Diagonal = 2
}

Как я могу написать процедуру, чтобы получить эти значения в System.Web.Mvc.SelectList, учитывая, что содержимое перечисления может быть изменено в будущем? Я хочу получить каждое имя перечисления в качестве текста опции и его значение как текст значения, например:

<select>
    <option value="0">Horizontal</option>
    <option value="1">Vertical</option>
    <option value="2">Diagonal</option>
</select>

Это лучшее, что я могу придумать до сих пор:

 public static SelectList GetDirectionSelectList()
 {
    Array values = Enum.GetValues(typeof(Direction));
    List<ListItem> items = new List<ListItem>(values.Length);

    foreach (var i in values)
    {
        items.Add(new ListItem
        {
            Text = Enum.GetName(typeof(Direction), i),
            Value = i.ToString()
        });
    }

    return new SelectList(items);
 }

Однако это всегда отображает текст опции как "System.Web.Mvc.ListItem". Отладка через это также показывает мне, что Enum.GetValues ​​() возвращает "Горизонтальный, вертикальный" и т.д. Вместо 0, 1, как я и ожидал, что заставляет меня задаться вопросом, какая разница между Enum.GetName() и Enum. ПолучитьЗначение().

4b9b3361

Ответ 1

Чтобы получить значение перечисления, вам нужно передать перечисление в его базовый тип:

Value = ((int)i).ToString();

Ответ 2

Прошло некоторое время с тех пор, как я должен был это сделать, но я думаю, что это должно сработать.

var directions = from Direction d in Enum.GetValues(typeof(Direction))
           select new { ID = (int)d, Name = d.ToString() };
return new SelectList(directions , "ID", "Name", someSelectedValue);

Ответ 4

Это то, что я только что сделал, и лично я считаю его сексуальным:

 public static IEnumerable<SelectListItem> GetEnumSelectList<T>()
        {
            return (Enum.GetValues(typeof(T)).Cast<T>().Select(
                enu => new SelectListItem() { Text = enu.ToString(), Value = enu.ToString() })).ToList();
        }

В конце концов, я собираюсь сделать некоторый перевод, поэтому Value = enu.ToString() будет делать что-то где-то.

Ответ 5

Я хотел сделать что-то очень похожее на решение Dann, но мне нужно, чтобы значение было int, а текст - строковым представлением Enum. Вот что я придумал:

public static IEnumerable<SelectListItem> GetEnumSelectList<T>()
    {
        return (Enum.GetValues(typeof(T)).Cast<int>().Select(e => new SelectListItem() { Text = Enum.GetName(typeof(T), e), Value = e.ToString() })).ToList();
    }

Ответ 6

Или:

foreach (string item in Enum.GetNames(typeof(MyEnum)))
{
    myDropDownList.Items.Add(new ListItem(item, ((int)((MyEnum)Enum.Parse(typeof(MyEnum), item))).ToString()));
}

Ответ 7

return
            Enum
            .GetNames(typeof(ReceptionNumberType))
            .Where(i => (ReceptionNumberType)(Enum.Parse(typeof(ReceptionNumberType), i.ToString())) < ReceptionNumberType.MCI)
            .Select(i => new
            {
                description = i,
                value = (Enum.Parse(typeof(ReceptionNumberType), i.ToString()))
            });

Ответ 8

возможно, не точный ответ на вопрос, но в сценариях CRUD я обычно реализую что-то вроде этого:

private void PopulateViewdata4Selectlists(ImportJob job)
{
   ViewData["Fetcher"] = from ImportFetcher d in Enum.GetValues(typeof(ImportFetcher))
                              select new SelectListItem
                              {
                                  Value = ((int)d).ToString(),
                                  Text = d.ToString(),
                                  Selected = job.Fetcher == d
                              };
}

PopulateViewdata4Selectlists вызывается перед представлением ( "Создать" ) и "Просмотр" ( "Редактировать" ), затем и в представлении:

<%= Html.DropDownList("Fetcher") %>

и что все..

Ответ 9

    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() };
        //var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = e, Name = e.ToString() };

        return new SelectList(values, "ID", "Name", enumObj);
    }
    public static SelectList ToSelectList<TEnum>(this TEnum enumObj, string selectedValue) 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() };
        //var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = e, Name = e.ToString() };
        if (string.IsNullOrWhiteSpace(selectedValue))
        {
            return new SelectList(values, "ID", "Name", enumObj);
        }
        else
        {
            return new SelectList(values, "ID", "Name", selectedValue);
        }
    }

Ответ 10

В ASP.NET Core MVC это делается с помощью тегов-помощников.

<select asp-items="Html.GetEnumSelectList<Direction>()"></select>

Ответ 11

У меня есть больше классов и методов по разным причинам:

Перечисление в коллекции элементов

public static class EnumHelper
{
    public static List<ItemDto> EnumToCollection<T>()
    {
        return (Enum.GetValues(typeof(T)).Cast<int>().Select(
            e => new ItemViewModel
                     {
                         IntKey = e,
                         Value = Enum.GetName(typeof(T), e)
                     })).ToList();
    }
}

Создание списка избранного в контроллере

int selectedValue = 1; // resolved from anywhere
ViewBag.Currency = new SelectList(EnumHelper.EnumToCollection<Currency>(), "Key", "Value", selectedValue);

MyView.cshtml

@Html.DropDownListFor(x => x.Currency, null, htmlAttributes: new { @class = "form-control" })

Ответ 12

У меня было много списков перечислений, и после большой охоты и просеивания выяснилось, что создание универсального помощника лучше всего подходит для меня. Он возвращает индекс или дескриптор в качестве значения Selectlist, а описание в виде текста Selectlist:

Enum:

public enum Your_Enum
{
    [Description("Description 1")]
    item_one,
    [Description("Description 2")]
    item_two
}

Помощник:

public static class Selectlists
{
    public static SelectList EnumSelectlist<TEnum>(bool indexed = false) where TEnum : struct
    {
        return new SelectList(Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(item => new SelectListItem
        {
            Text = GetEnumDescription(item as Enum),
            Value = indexed ? Convert.ToInt32(item).ToString() : item.ToString()
        }).ToList(), "Value", "Text");
    }

    // NOTE: returns Descriptor if there is no Description
    private static string GetEnumDescription(Enum 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();
    }
}

Применение: Установите для параметра значение "true" для индексов как значение:

var descriptorsAsValue = Selectlists.EnumSelectlist<Your_Enum>();
var indicesAsValue = Selectlists.EnumSelectlist<Your_Enum>(true);