【问题标题】:How to get the values of an enum into a SelectList如何将枚举的值放入 SelectList
【发布时间】:2010-11-09 18:02:45
【问题描述】:

假设我有一个这样的枚举(仅作为示例):

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() 正在返回 'Horizo​​ntal、Vertical' 等,而不是我预期的 0、1,这让我想知道 Enum.GetName() 和 Enum 之间有什么区别。获取值()。

【问题讨论】:

标签: c# asp.net-mvc enums


【解决方案1】:

我不得不这样做已经有一段时间了,但我认为这应该可行。

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

【讨论】:

  • 几乎可以工作,只需要稍作改动!当 OP 希望它是整数时,您的代码会将值设置为 Text。不过很容易修复。将 ID = d 更改为 ID = (int)d。感谢您发布此内容,我从来没有想过!
  • 很好的答案,虽然我发现要预先填充下拉列表,该值必须是枚举的文本表示形式,而不是整数。
【解决方案2】:

ASP.NET MVC 5.1 中有一个新特性。

http://www.asp.net/mvc/overview/releases/mvc51-release-notes#Enum

@Html.EnumDropDownListFor(model => model.Direction)

【讨论】:

  • 这个有taghelper 版本吗?
  • @SerjSagan,是的。 &lt;select asp-items="Html.GetEnumSelectList&lt;Direction&gt;()"&gt;&lt;/select&gt;.
  • 如何从控制器中获取选定的值?
【解决方案3】:

这是我刚刚制作的,我个人认为它很性感:

 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() 会在某处调用某些东西。

【讨论】:

  • 我对这段代码有疑问。 SelectList 的“Value”与“Text”相同。将 Enums 与 EntityFramework 一起使用时,保存回数据库的值必须是 int。
  • 好的,那就这样做吧:Value = (int)enu
  • 上例中 (int)enu 不起作用的原因是因为 SelectListItem 的 Value 属性是字符串而不是整数。 ((int)enu).ToString() 将起作用。
  • 不,不会的。在上面的示例中,在编译时它不知道T 的类型。因此,您不能像那样投射到int
  • 从 C# 7.3 开始,您现在可以添加 'where T : System.Enum'。
【解决方案4】:

要获取枚举的值,您需要将枚举转换为其基础类型:

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

【讨论】:

  • 谢谢!我考虑过这一点,但认为可能有一种方法可以在不强制转换的情况下做到这一点。
【解决方案5】:

我想做一些与 Dann 的解决方案非常相似的事情,但我需要 Value 是一个 int 并且 text 是 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();
    }

【讨论】:

  • 这是迄今为止更好的答案。值需要是枚举的 int 表示形式。
【解决方案6】:

在 ASP.NET Core MVC 中,这是通过 tag helpers 完成的。

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

【讨论】:

  • 如何在加载时设置选定的?
  • 那你需要指定asp-for属性。
【解决方案7】:

也许不是这个问题的确切答案,但在 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 在 View("Create") 和 View("Edit") 之前调用,然后在 View 中调用:

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

仅此而已..

【讨论】:

    【解决方案8】:

    或者:

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

    【讨论】:

      【解决方案9】:
      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()))
                  });
      

      【讨论】:

        【解决方案10】:
            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);
                }
            }
        

        【讨论】:

          【解决方案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 值返回,并将 Description 作为 Selectlist 文本返回:

            枚举:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-03-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-08-11
              相关资源
              最近更新 更多