如何使用枚举值填充下拉列表?

时间:2010-09-14 00:17:51

标签: asp.net-mvc generics enums ienumerable

我有一个枚举我的视图模型的一个属性。我想显示一个下拉列表,其中包含枚举的所有值。我可以使用以下代码来实现此目的。

我想知道是否有一种简单的方法可以从枚举转换为IEnumerable?我可以手动执行,如下例所示,但是当我添加新的枚举值时,代码会中断。我想我可以按照example通过反射来做到这一点,但是还有其他方法可以做到这一点吗?

public enum Currencies
{
  CAD, USD, EUR
}

public ViewModel
{
  [Required]
  public Currencies SelectedCurrency {get; set;}

  public SelectList Currencies
  {
    List<Currencies> c = new List<Currencies>();
    c.Add(Currencies.CAD);
    c.Add(Currencies.USD);
    c.Add(Currencies.EUR);

    return new SelectList(c);
  }
}

5 个答案:

答案 0 :(得分:18)

我正在使用帮助器,我发现here使用通用枚举类型填充我的SelectLists,我做了一些修改以添加所选值,但这是它的样子:

public static SelectList ToSelectList<T>(this T enumeration, string selected)
{
    var source = Enum.GetValues(typeof(T));

    var items = new Dictionary<object, string>();

    var displayAttributeType = typeof(DisplayAttribute);

    foreach (var value in source)
    {
        FieldInfo field = value.GetType().GetField(value.ToString());

        DisplayAttribute attrs = (DisplayAttribute)field.
                      GetCustomAttributes(displayAttributeType, false).FirstOrDefault()

        items.Add(value, attrs != null ? attrs.GetName() : value.ToString());
    }

    return new SelectList(items, "Key", "Value", selected);
}

关于它的好处是它将DisplayAttribute读作标题而不是枚举名称。 (如果你的枚举包含空格或者你需要本地化,那么它会让你的生活更轻松)

因此,您需要将Display attirubete添加到您的枚举中,如下所示:

public enum User_Status
{
    [Display(Name = "Waiting Activation")]
    Pending,    // User Account Is Pending. Can Login / Can't participate

    [Display(Name = "Activated" )]
    Active,                // User Account Is Active. Can Logon

    [Display(Name = "Disabled" )]
    Disabled,          // User Account Is Diabled. Can't Login
}

这就是你在视图中使用它们的方式。

<%: Html.DropDownList("ChangeStatus" , ListExtensions.ToSelectList(Model.statusType, user.Status))%>

Model.statusType只是User_Status类型的枚举对象。

就是这样,ViewModel中不再有SelectLists。在我的示例中,我正在我的ViewModel中重新生成枚举,但您可以直接在视图中参考枚举类型。我只是这样做,让一切都干净整洁。

希望这很有用。

答案 1 :(得分:2)

查看Enum.GetNames(typeof(货币))

答案 2 :(得分:2)

我在这个问题上已经很晚了,但是如果您愿意添加Unconstrained Melody NuGet包(Jon Skeet的一个不错的小型库),我只想用一行代码找到一个非常酷的方法。 )。

此解决方案更好,因为:

  1. 它确保(使用泛型类型约束)该值实际上是枚举值(由于无约束旋律)
  2. 避免不必要的拳击(由于Unconstrained Melody)
  3. 它缓存所有描述以避免在每次调用时使用反射(由于无约束旋律)
  4. 它的代码少于其他解决方案!
  5. 所以,以下是实现这一目标的步骤:

    1. 在软件包管理器控制台中,“Install-Package UnconstrainedMelody”
    2. 在模型上添加属性,如下所示:

      //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() });
          }
      }
      
    3. 现在您已在模型上公开了ListListItem,您可以使用@ Html.DropDownList或@ Html.DropDownListFor将此属性用作源。

答案 3 :(得分:1)

这么多好的答案 - 我想我会添加我的解决方案 - 我在视图中构建SelectList(而不是在Controller中):

在我的c#中:

namespace ControlChart.Models
//My Enum
public enum FilterType { 
[Display(Name = "Reportable")]    
Reportable = 0,    
[Display(Name = "Non-Reportable")]    
NonReportable,    
[Display(Name = "All")]    
All };

//My model:
public class ChartModel {  
[DisplayName("Filter")]  
public FilterType Filter { get; set; }
}

在我的cshtml中:

@using System.ComponentModel.DataAnnotations
@using ControlChart.Models
@model ChartMode
@*..........*@
@Html.DropDownListFor(x => x.Filter,                           
from v in (ControlChart.Models.FilterType[])(Enum.GetValues(typeof(ControlChart.Models.FilterType)))
select new SelectListItem() {
    Text = ((DisplayAttribute)(typeof(FilterType).GetField(v.ToString()).GetCustomAttributes(typeof(DisplayAttribute), false).First())).Name,                             
    Value = v.ToString(),                             
    Selected = v == Model.Filter                           
    })

HTH

答案 4 :(得分:1)

也许为时已晚,但我认为对于有同样问题的人来说这可能有用。 我发现here现在使用MVC 5,它包含了一个 EnumDropDownListFor html帮助程序,不再需要使用自定义帮助程序或其他解决方法。

在这种特殊情况下,只需添加:

    @Html.EnumDropDownListFor(x => x.SelectedCurrency)

就是这样!

您还可以通过数据注释和资源文件翻译或更改显示的文本:

  1. 将以下数据注释添加到枚举中:

    public enum Currencies
    {
        [Display(Name="Currencies_CAD", ResourceType=typeof(Resources.Enums)]  
        CAD, 
        [Display(Name="Currencies_USD", ResourceType=typeof(Resources.Enums)]    
        USD,
        [Display(Name="Currencies_EUR", ResourceType=typeof(Resources.Enums)]  
        EUR
    }
    
  2. 创建相应的资源文件。