【问题标题】:How can I convert an enumeration into a List<SelectListItem>?如何将枚举转换为 List<SelectListItem>?
【发布时间】:2011-03-30 04:50:18
【问题描述】:

我有一个 asp.net-mvc 网页,我想显示一个基于枚举的下拉列表。我想显示每个枚举项的文本,id 是与枚举关联的 int 值。有什么优雅的方式来进行这种转换吗?

【问题讨论】:

  • 马克西姆 Vi 的答案。应该是正确的答案。

标签: c# asp.net-mvc enums selectlistitem


【解决方案1】:

在 Asp.Net Core 中,只需使用:

<select asp-for="MyEnum" asp-items="Html.GetEnumSelectList(typeof(MyEnum))"></select>

或者

创建助手

public static class EnumHelper
{
    public static IEnumerable<SelectListItem> GetEnumSelectList<TEnum>(bool isNullable = false)
        where TEnum : struct
    {
        IList<SelectListItem> selectLists = Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(c => new SelectListItem()
        {
            Text = GetDisplayName(c),
            Value = c.ToString()
        }).ToList();

        if (isNullable)
        {
            selectLists.Add(new SelectListItem());
        }

        return selectLists.OrderBy(c => c.Value);
    }

    public static string GetDisplayName<TEnum>(TEnum enumVal)
    {
        DisplayAttribute attr = GetAttribute<DisplayAttribute>(enumVal);

        if (attr != null)
        {
            return attr.Name;
        }

        return enumVal?.ToString() ?? string.Empty;
    }

    public static TEnum GetAttribute<TEnum>(object enumVal) where TEnum : Attribute
    {
        if (enumVal == null)
        {
            return default;
        }

        Type type = enumVal.GetType();
        MemberInfo[] memInfo = type.GetMember(enumVal.ToString());

        if (memInfo.Length == 0)
        {
            return null;
        }

        object[] attributes = memInfo[0].GetCustomAttributes(typeof(TEnum), false);
        return attributes.Length > 0 ? (TEnum)attributes[0] : null;
    }
}

使用

@using MyClass.Helpers;
    
<select asp-for="MyEnum" asp-items="EnumHelper.GetEnumSelectList<MyEnum>(true)">/select>

【讨论】:

    【解决方案2】:

    使用我的扩展方法非常简单。它还允许您提供选项,例如添加占位符、分组和禁用某些值或组。试试看吧。

    enum Color
    {       
        Blue,
        [Category("Light")]
        [DisplayName("Light Blue")]
        LBlue,
        [Category("Dark")]
        [DisplayName("Dark Blue")]
        DBlue,
        Red,
        [Category("Dark")]
        [DisplayName("Dark Red")]
        DRed,
        [Category("Light")]
        [DisplayName("Light Red")]
        LRed,
        Green,
        [Category("Dark")]
        [DisplayName("Dark Green")]
        DGreen,
        [Category("Light")]
        [DisplayName("Light Green")]
        LGreen  
    }
    
    var list = typeof(Color).ToSelectList();
    
    //or with custom options
    var list = typeof(Color).ToSelectList(new SelectListOptions { Placeholder = "Please Select A Color"});
    

    Here's the link to the github repo.

    【讨论】:

      【解决方案3】:

      我使用了 Html Helper 类中的 GetEnumSelectList

      <select asp-for="MyProperty" class="form-control" asp-items="@Html.GetEnumSelectList<MyEnum>()" ></select>
      

      【讨论】:

        【解决方案4】:

        我使用可以重复使用的静态方法来完成这项工作。

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

        【讨论】:

          【解决方案5】:

          从 MVC 5.1 开始,如果您需要在视图中填充 select 选项,最优雅的方法是使用 Html 助手的 EnumDropDownListFor 方法:

          @Html.EnumDropDownListFor(m => m.MyEnumProperty,new { @class="form-control"})
          

          或控制器中 EnumHelper 的 GetSelectList 方法:

          var enumList = EnumHelper.GetSelectList(typeof (MyEnum));
          

          【讨论】:

          • 非常漂亮!不知道这个...应该是正确的答案。
          • 哇,我不知道。现在节省了很多代码行!谢谢你!
          • 对于那些想了解 EnumHelper 的人,请执行以下操作:Html.DropDownList("SearchEnum", EnumHelper.GetSelectList(typeof(MyEnum)))
          • 我喜欢这个答案。我完全忘记了 EnumDropDownListFor.. 如果你使用 IEnumerable 会发生什么?
          【解决方案6】:

          您可以使用 LINQ:

          Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Select(v => new SelectListItem {
              Text = v.ToString(),
              Value = ((int)v).ToString()
          }).ToList();
          

          【讨论】:

          • 虽然 LINQ 已成为 Enumerable Extensions 的非官方名称,但我不禁想知道是否存在更合适的名称。
          • 它是 Linq 命名空间和项目的一部分,IMO 是正确的名称。 Linq 也是语言扩展的名称。
          • 上面这段代码没有编译。我正在尝试这样做: List dropdown = Enum.GetValues(typeof(EventType)).Select(v => new SelectListItem { Selected = (int)v == id, Text = v.ToString(), Value = ((int)v).ToString() }).ToList();返回下拉列表;但在执行 (int)v) 的行中出现错误:“无法将表达式从 TSource 转换为 int”
          • 你可以说:“你可以使用 System.Linq”
          • @SLaks 好点,但它没有考虑 Order in Display 属性
          【解决方案7】:

          您可以使用Enum.GetNames() 获取包含枚举项名称的字符串数组。如果您的项目名称是用户友好的,那么这可能就足够了。否则,您可以创建自己的 GetName() 方法,该方法将为每个项目返回一个好听的名称。

          或者 - 如果枚举永远不会(或很少)更改,您可以创建一个直接将硬编码项目添加到下拉列表的方法。这可能更有效(如果这对您很重要)。

          【讨论】:

            【解决方案8】:

            现在我使用了Tuple&lt;string, string&gt;,但您可以将其转换为使用任何东西:

            var values = Enum.GetValues(typeof(DayOfWeek))
                .Cast<DayOfWeek>()
                .Select(d => Tuple.Create(((int)d).ToString(), d.ToString()))
                .ToList()
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-05-07
              • 2016-03-20
              • 2010-09-06
              相关资源
              最近更新 更多