views:

1109

answers:

4

Hi All,

Imagine I have an enumeration such as this (just as an example):

public enum Direction{
    Horizontal = 0,
    Vertical = 1,
    Diagonal = 2
}

How can I write a routine to get these values into a System.Web.Mvc.SelectList, given that the contents of the enumeration are subject to change in future? I want to get each enumerations name as the option text, and its value as the value text, like this:

<select>
    <option value="0">Horizontal</option>
    <option value="1">Vertical</option>
    <option value="2">Diagonal</option>
</select>

This is the best I can come up with so far:

 public static SelectList GetDirectionSelectList()
 {
    Array values = Enum.GetValues(typeof(Direction));
    List<ListItem> items = new List<ListItem>(values.Length);

    foreach (var i in values)
    {
        items.Add(new ListItem
        {
            Text = Enum.GetName(typeof(Direction), i),
            Value = i.ToString()
        });
    }

    return new SelectList(items);
 }

However this always renders the option text as 'System.Web.Mvc.ListItem'. Debugging through this also shows me that Enum.GetValues() is returning 'Horizontal, Vertical' etc. instead of 0, 1 as I would've expected, which makes me wonder what the difference is between Enum.GetName() and Enum.GetValue().

Thanks!

+5  A: 

To get the value of an enum you need to cast the enum to its underlying type:

Value = ((int)i).ToString();
Andrew Hare
Thanks! I thought about this but thought there might be a way to do it without casting.
Lee D
+6  A: 

It's been awhile since I've had to do this, but I think this should work.

var directions = from Direction d in Enum.GetValues(typeof(Direction))
           select new { ID = d, Name = d.ToString() };
return new SelectList(directions , "ID", "Name", someSelectedValue);
Brandon
Almost works, only needs a minor change! Your code will set the value to the Text when the OP wanted it to be an integer. Easy fix though. Change `ID = d` to `ID = (int)d`. Thanks for posting this, I never would have thought of it!
Chris
A: 

maybe not an exact answer to the question, but in CRUD scenarios i usually implements something like this:

private void PopulateViewdata4Selectlists(ImportJob job)
{
   ViewData["Fetcher"] = from ImportFetcher d in Enum.GetValues(typeof(ImportFetcher))
                              select new SelectListItem
                              {
                                  Value = ((int)d).ToString(),
                                  Text = d.ToString(),
                                  Selected = job.Fetcher == d
                              };
}

PopulateViewdata4Selectlists is called before View("Create") and View("Edit"), then and in the View:

<%= Html.DropDownList("Fetcher") %>

and that's all..

Carl Hörberg
A: 

This is what I have just made and personally I think its sexy:

 public static IEnumerable<SelectListItem> GetEnumSelectList<T>()
        {
            return (Enum.GetValues(typeof(T)).Cast<T>().Select(
                enu => new SelectListItem() { Text = enu.ToString(), Value = enu.ToString() })).ToList();
        }

I am going to do some translation stuff eventually so the Value = enu.ToString() will do a call out to something somewhere.

burnt_hand