How do I populate a dropdownlist with enum values?

前端 未结 5 1035
栀梦
栀梦 2020-12-03 12:32

I have an enum for one of the properties of my view-model. I want to display a drop-down list that contains all the values of the enum. I can get this to work with the fol

相关标签:
5条回答
  • 2020-12-03 13:06

    Look at Enum.GetNames(typeof(Currencies))

    0 讨论(0)
  • 2020-12-03 13:09

    Maybe is too late, but i think it could be useful for people with the same problem. I've found here that now with MVC 5 it's included an EnumDropDownListFor html helper that makes for no longer necesary the use of custom helpers or other workarounds.

    In this particular case, just add this:

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

    and that's all!

    You can also translate or change the displayed text via data annotations and resources files:

    1. Add the following data annotations to your enum:

      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. Create the corresponding resources file.

    0 讨论(0)
  • 2020-12-03 13:16

    So many good answers - I thought I'sd add my solution - I am building the SelectList in the view (and not in the Controller):

    In my 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; }
    }
    

    In my 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

    0 讨论(0)
  • 2020-12-03 13:22

    I'm using a helper that i found here to populate my SelectLists with a generic enum type, i did a little modification to add the selected value though, here's how it looks like :

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

    The nice thing about it is that it reads the DisplayAttribute as the title rather than the enum name. (if your enums contain spaces or you need localization then it makes your life much easier)

    So you will need to add the Display attirubete to your enums like this :

    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
    }
    

    and this is how you use them in your views.

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

    Model.statusType is just an enum object of type User_Status.

    That's it , no more SelectLists in your ViewModels. In my example I'm refrencing an enum in my ViewModel but you can Refrence the enum type directly in your view though. I'm just doing it to make everything clean and nice.

    Hope that was helpful.

    0 讨论(0)
  • 2020-12-03 13:23

    I am very late on this one but I just found a really cool way to do this with one line of code, if you are happy to add the Unconstrained Melody NuGet package (a nice, small library from Jon Skeet).

    This solution is better because:

    1. It ensures (with generic type constraints) that the value really is an enum value (due to Unconstrained Melody)
    2. It avoids unnecessary boxing (due to Unconstrained Melody)
    3. It caches all the descriptions to avoid using reflection on every call (due to Unconstrained Melody)
    4. It is less code than the other solutions!

    So, here are the steps to get this working:

    1. In Package Manager Console, "Install-Package UnconstrainedMelody"
    2. Add a property on your model like so:

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

    Now that you have the List of SelectListItem exposed on your model, you can use the @Html.DropDownList or @Html.DropDownListFor using this property as the source.

    0 讨论(0)
提交回复
热议问题