Как создать выпадающий список из перечисления в ASP.NET MVC?

У меня была такая же проблема, и я потратил около часа на то, чтобы решить проблему. В конце концов, это был символ «#» в пути.

Итак, я переименовал «C: \ # IDE \ eclipse 3.7 \» в «C: \ + IDE \ eclipse 3.7 \» и решил проблема.

640
задан 5 revs, 5 users 56% 27 February 2019 в 10:26
поделиться

6 ответов

Поскольку MVC v5.1 использует HTML. EnumDropDownListFor

@Html.EnumDropDownListFor(
    x => x.YourEnumField,
    "Select My Type", 
    new { @class = "form-control" })

Поскольку MVC v5 использует EnumHelper

@Html.DropDownList("MyType", 
   EnumHelper.GetSelectList(typeof(MyType)) , 
   "Select My Type", 
   new { @class = "form-control" })

Для MVC 5 и ниже

Я прокрутил ответ Rune в дополнительный метод:

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);
        }
    }
}

Это позволяет Вам писать:

ViewData["taskStatus"] = task.Status.ToSelectList();

using MyApp.Common

817
ответ дан 22 November 2019 в 21:47
поделиться

ОБНОВИЛ - я предложу использовать предложение Rune ниже, а не этой опцией!

<час>

я предполагаю, что Вы хотите что-то как выполнение до конца размолвкой:

<select name="blah">
    <option value="1">Movie</option>
    <option value="2">Game</option>
    <option value="3">Book</option>
</select>

, который Вы могли сделать с дополнительным методом что-то как следующее:

public static string DropdownEnum(this System.Web.Mvc.HtmlHelper helper,
                                  Enum values)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    sb.Append("<select name=\"blah\">");
    string[] names = Enum.GetNames(values.GetType());
    foreach(string name in names)
    {
        sb.Append("<option value=\"");
        sb.Append(((int)Enum.Parse(values.GetType(), name)).ToString());
        sb.Append("\">");
        sb.Append(name);
        sb.Append("</option>");
    }
    sb.Append("</select>");
    return sb.ToString();
}

, НО вещи как это не локализуемы (т.е. будет трудно перевести на другой язык).

Примечание: необходимо назвать статический метод с экземпляром Перечисления, т.е. Html.DropdownEnum(ItemTypes.Movie);

может быть более изящный способ сделать это, но вышеупомянутое действительно работает.

-6
ответ дан Ash 27 February 2019 в 10:26
поделиться
  • 1
    Хороший ответ. I' ll просто добавляют это если you' ре, собирающееся позволить ввод данных пользователем Вашей веб-странице, рассмотрите использование strip_tags (), чтобы препятствовать тому, чтобы люди добавили < script>. – Andrioid 5 September 2010 в 05:50

Вы хотите посмотреть на использование чего-то как Enum.GetValues

8
ответ дан 2 revs, 2 users 86% 27 February 2019 в 10:26
поделиться
  • 1
    С другой стороны, .rsplit (":" 1) [-1], который разделяет самое большее однажды (от правого конца). – MRAB 29 May 2011 в 19:55

Я врезался в ту же проблему, нашел этот вопрос и думал, что решение, предоставленное Ash, не было тем, что я искал; Необходимость создать HTML самостоятельно означает меньше гибкости по сравнению со встроенным Html.DropDownList() функция.

Оказывается, что C#3 и т.д. делает это довольно легким. Я имею enum названный 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);

Это создает старое доброе SelectList, который может использоваться как, Вы привыкли к в представлении:

<td><b>Status:</b></td><td><%=Html.DropDownList("taskStatus")%></td></tr>

анонимный тип и LINQ делают это настолько более изящным, по моему скромному мнению. Никакое предназначенное преступление, Ash. :)

127
ответ дан 2 revs, 2 users 91% 27 February 2019 в 20:26
поделиться

Развивая ответы Призе и Руна, если вы хотите, чтобы атрибут value элементов списка select сопоставляются с целочисленным значением типа Enumeration, а не со строковым значением, используйте следующий код:

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);
}

Вместо того, чтобы рассматривать каждое значение Enumeration как объект TEnum, мы можем рассматривать его как объект, а затем привести его к целому числу, чтобы получить распаковка значения.

Примечание: Я также добавил универсальное ограничение типа, чтобы ограничить типы, для которых это расширение доступно, только структурами (базовый тип Enum), и проверку типа во время выполнения, которая гарантирует, что переданная структура действительно является Enum.

Обновление 23.10.12: Добавлен параметр универсального типа для базового типа и исправлена проблема без компиляции, влияющая на .NET 4+.

22
ответ дан 22 November 2019 в 21:47
поделиться

Чтобы решить проблему получения числа вместо текста, используя метод расширения 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);
}
10
ответ дан 22 November 2019 в 21:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: