How do you create a dropdownlist from an enum in ASP.NET MVC?

后端 未结 30 1909
不知归路
不知归路 2020-11-21 16:36

I\'m trying to use the Html.DropDownList extension method but can\'t figure out how to use it with an enumeration.

Let\'s say I have an enumeration like

相关标签:
30条回答
  • 2020-11-21 17:06

    Html.DropDownListFor only requires an IEnumerable, so an alternative to Prise's solution is as follows. This will allow you to simply write:

    @Html.DropDownListFor(m => m.SelectedItemType, Model.SelectedItemType.ToSelectList())
    

    [Where SelectedItemType is a field on your model of type ItemTypes, and your model is non-null]

    Also, you don't really need to genericize the extension method as you can use enumValue.GetType() rather than typeof(T).

    EDIT: Integrated Simon's solution here as well, and included ToDescription extension method.

    public static class EnumExtensions
    {
        public static IEnumerable<SelectListItem> ToSelectList(this Enum enumValue)
        {
            return from Enum e in Enum.GetValues(enumValue.GetType())
                   select new SelectListItem
                   {
                       Selected = e.Equals(enumValue),
                       Text = e.ToDescription(),
                       Value = e.ToString()
                   };
        }
    
        public static string ToDescription(this Enum value)
        {
            var attributes = (DescriptionAttribute[])value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
            return attributes.Length > 0 ? attributes[0].Description : value.ToString();
        }
    }
    
    0 讨论(0)
  • 2020-11-21 17:06

    This is my version of helper method. I use this:

    var values = from int e in Enum.GetValues(typeof(TEnum))
                 select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) };
    

    Instead of that:

    var values = from TEnum e in Enum.GetValues(typeof(TEnum))
               select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString())
                         , Name = e.ToString() };
    

    Here it is:

    public static SelectList ToSelectList<TEnum>(this TEnum self) where TEnum : struct
        {
            if (!typeof(TEnum).IsEnum)
            {
                throw new ArgumentException("self must be enum", "self");
            }
    
            Type t = typeof(TEnum);
    
            var values = from int e in Enum.GetValues(typeof(TEnum))
                         select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) };
    
            return new SelectList(values, "ID", "Name", self);
        }
    
    0 讨论(0)
  • 2020-11-21 17:07

    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)
  • 2020-11-21 17:07

    I ended up creating extention methods to do what is essentially the accept answer here. The last half of the Gist deals with Enum specifically.

    https://gist.github.com/3813767

    0 讨论(0)
  • 2020-11-21 17:07
    @Html.DropDownListFor(model => model.MaritalStatus, new List<SelectListItem> 
    {  
    
    new SelectListItem { Text = "----Select----", Value = "-1" },
    
    
    new SelectListItem { Text = "Marrid", Value = "M" },
    
    
     new SelectListItem { Text = "Single", Value = "S" }
    
    })
    
    0 讨论(0)
  • 2020-11-21 17:08

    A super easy way to get this done - without all the extension stuff that seems overkill is this:

    Your enum:

        public enum SelectedLevel
        {
           Level1,
           Level2,
           Level3,
           Level4
        }
    

    Inside of your controller bind the Enum to a List:

        List<SelectedLevel> myLevels = Enum.GetValues(typeof(SelectedLevel)).Cast<SelectedLevel>().ToList();
    

    After that throw it into a ViewBag:

        ViewBag.RequiredLevel = new SelectList(myLevels);
    

    Finally simply bind it to the View:

        @Html.DropDownList("selectedLevel", (SelectList)ViewBag.RequiredLevel, new { @class = "form-control" })
    

    This is by far the easiest way I found and does not require any extensions or anything that crazy.

    UPDATE: See Andrews comment below.

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