7

I have a Enum called CityType

public enum CityType
    {
        [Description("Select City")]
        Select = 0,

        [Description("A")]
        NewDelhi = 1,

        [Description("B")]
        Mumbai = 2,

        [Description("C")]
        Bangalore = 3,

        [Description("D")]
        Buxar = 4,

        [Description("E")]
        Jabalpur = 5
    }

Generate List from Enum

IList<SelectListItem> list = Enum.GetValues(typeof(CityType)).Cast<CityType>().Select(x =>    new SelectListItem(){ 
    Text = EnumHelper.GetDescription(x), 
    Value = ((int)x).ToString()
}).ToList(); 

int city=0; 
if (userModel.HomeCity != null) city= (int)userModel.HomeCity;
ViewData["HomeCity"] = new SelectList(list, "Value", "Text", city);

Bind on .cshtml

@Html.DropDownList("HomeCity",null,new { @style = "width:155px;", @class = "form-control" })

EnumHelper GetDescription Class to get Description of Enum

Community
  • 1
  • 1
Satish Singh
  • 2,169
  • 3
  • 23
  • 32
  • So what is your problem? And your `enum` should not contain the `Select = 0` value. You create the `null` option using an overload of `DropDownList()` that accepts a `labelOption`. And to do this correctly, refer the answers [here](http://stackoverflow.com/questions/388483/how-do-you-create-a-dropdownlist-from-an-enum-in-asp-net-mvc) –  Jan 22 '17 at 01:39
  • Related: https://stackoverflow.com/questions/17280906/binding-an-enum-to-a-dropdownlist-in-mvc-4/17281798 – Graham May 30 '17 at 15:10

2 Answers2

3

I blogged about this very subject whereby I create an EnumHelper to help with this common task.

http://jnye.co/Posts/4/creating-a-dropdown-list-from-an-enum-in-mvc-and-c%23

In your controller:

//If you don't have an enum value use the type
ViewBag.DropDownList = EnumHelper.SelectListFor<MyEnum>();

//If you do have an enum value use the value (the value will be marked as selected)    
ViewBag.DropDownList = EnumHelper.SelectListFor(MyEnum.MyEnumValue);

In your View:

@Html.DropDownList("DropDownList")
@* OR *@
@Html.DropDownListFor(m => m.Property, ViewBag.DropDownList as SelectList, null)

The helper class:

public static class EnumHelper
{
    // Get the value of the description attribute if the   
    // enum has one, otherwise use the value.  
    public static string GetDescription<TEnum>(this TEnum value)
    {
        var fi = value.GetType().GetField(value.ToString());

        if (fi != null)
        {
            var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

            if (attributes.Length > 0)
            {
                return attributes[0].Description;
            }
        }

        return value.ToString();
    }

    /// <summary>
    /// Build a select list for an enum
    /// </summary>
    public static SelectList SelectListFor<T>() where T : struct
    {
        Type t = typeof(T);
        return !t.IsEnum ? null
                         : new SelectList(BuildSelectListItems(t), "Value", "Text");
    }

    /// <summary>
    /// Build a select list for an enum with a particular value selected 
    /// </summary>
    public static SelectList SelectListFor<T>(T selected) where T : struct
    {
        Type t = typeof(T);
        return !t.IsEnum ? null
                         : new SelectList(BuildSelectListItems(t), "Text", "Value", selected.ToString());
    }

    private static IEnumerable<SelectListItem> BuildSelectListItems(Type t)
    {
        return Enum.GetValues(t)
                   .Cast<Enum>()
                   .Select(e => new SelectListItem { Value = e.ToString(), Text = e.GetDescription() });
    }
}
NinjaNye
  • 7,046
  • 1
  • 32
  • 46
2

This is the code I use for enums in dropdowns. Then just use @Html.DropDown/For(); and put this SelectList in as param.

public static SelectList ToSelectList(this Type enumType, string selectedValue)
    {
        var items = new List<SelectListItem>();
        var selectedValueId = 0;
        foreach (var item in Enum.GetValues(enumType))
        {
            FieldInfo fi = enumType.GetField(item.ToString());
            DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
            var title = "";
            if (attributes != null && attributes.Length > 0)
            {
                title = attributes[0].Description;
            }
            else
            {
                title = item.ToString();
            }

            var listItem = new SelectListItem
            {
                Value = ((int)item).ToString(),
                Text = title,
                Selected = selectedValue == ((int)item).ToString(),
            };
            items.Add(listItem);
        }

        return new SelectList(items, "Value", "Text", selectedValueId);
    }

Also you can extend DropDownFor like this:

public static MvcHtmlString EnumDropdownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType, object htmlAttributes = null)
    {
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

        SelectList selectList = enumType.ToSelectList(metadata.Model.ToString());

        return htmlHelper.DropDownListFor(expression, selectList, htmlAttributes);
    }

Usage then looks like this:

@Html.EnumDropdownListFor(model => model.Property, typeof(SpecificEnum))
TheCodeDestroyer
  • 763
  • 9
  • 29
  • What is the EnumExtension.ToSelectList? That a custom class? – Seth Dec 05 '14 at 20:13
  • Its just a class where this ToSelectList() method lives. Altho it would be cleaner to use the enumType param as `this`, so you would then use it like: `enumType.ToSelectList(metadata.Model.ToString())` I can change the answer to show this usage if you want. – TheCodeDestroyer Dec 08 '14 at 07:55
  • Yes can you please update cause i can't seem to get it. Do i need to create a ToSelectList, cause its not avialble? Thanks! – Seth Dec 09 '14 at 19:56
  • Ok updated ToSelectList list and EnumDropdownListFor methods. – TheCodeDestroyer Dec 10 '14 at 10:58
  • Thanks for the example. I have changed enumType.ToSelectList(metadata.Model.ToString()) to metadata.ModelType.ToSelectList(metadata.Model.ToString()). But I had to change method name to avoid ambigous method call. – isaolmez Oct 19 '15 at 16:56