代码之家  ›  专栏  ›  技术社区  ›  yamspog

如何用枚举值填充DropDownList?

  •  8
  • yamspog  · 技术社区  · 15 年前

    我有一个视图模型属性的枚举。我想显示一个下拉列表,其中包含枚举的所有值。我可以让它与下面的代码一起工作。

    我想知道是否有一种简单的方法可以从枚举转换为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 回复  |  直到 10 年前
        1
  •  18
  •   Manaf Abu.Rous    12 年前

    我在找一个帮手 here 为了用通用枚举类型填充selectlist,我做了一些修改以添加所选值,但是如下所示:

    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 .

    就是这样,视图模型中不再有选择列表。在我的示例中,我正在我的视图模型中重新引用枚举,但是您可以直接在视图中重新引用枚举类型。我这样做只是为了让一切变得干净和美好。

    希望有帮助。

        2
  •  2
  •   Oleg D.    15 年前

    查看enum.getnames(typeof(currencys))。

        3
  •  2
  •   nootn    13 年前

    我已经很晚了,但我只是找到了一个非常酷的方法,用一行代码来完成这项工作,如果您愿意添加 Unconstrained Melody Nuget软件包(乔恩·斯基特的一个不错的小图书馆)。

    此解决方案更好,因为:

    1. 它确保(使用泛型类型约束)值实际上是枚举值(由于旋律不受约束)
    2. 避免不必要的拳击(由于旋律不受约束)
    3. 它缓存所有描述,以避免在每次调用时使用反射(由于旋律不受约束)
    4. 它的代码比其他解决方案少!

    因此,以下是实现这一目标的步骤:

    1. 在包管理器控制台中,“安装包未经培训的日志”
    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() });
          }
      }
      

    既然模型中已经公开了selectListItem的列表,那么可以使用@html.dropdownlist或@html.dropdownlist将此属性用作源。

        4
  •  1
  •   Luchian    14 年前

    这么多好的答案-我以为我要添加我的解决方案-我正在视图中构建选择列表(而不是在控制器中):

    在我的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                           
        })
    

    高温高压

        5
  •  1
  •   redcap    11 年前

    也许为时已晚,但我认为这对有同样问题的人可能是有用的。 我找到了 here 现在MVC 5包括 EnumDropDownList用于 不再需要使用自定义帮助程序或其他解决方法的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. 创建相应的资源文件。

    推荐文章