So erhalten Sie die Werte einer Aufzählung in eine SelectList


71

Stellen Sie sich vor, ich habe eine Aufzählung wie diese (nur als Beispiel):

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

Wie kann ich eine Routine schreiben, um diese Werte in eine System.Web.Mvc.SelectList zu übernehmen, da sich der Inhalt der Aufzählung in Zukunft ändern kann? Ich möchte jeden Aufzählungsnamen als Optionstext und seinen Wert als Wertetext wie folgt erhalten:

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

Dies ist das Beste, was ich bisher finden kann:

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

Dadurch wird der Optionstext jedoch immer als "System.Web.Mvc.ListItem" dargestellt. Das Debuggen zeigt mir auch, dass Enum.GetValues ​​() wie erwartet 'Horizontal, Vertikal' usw. anstelle von 0, 1 zurückgibt, was mich fragen lässt, was der Unterschied zwischen Enum.GetName () und Enum ist. Wert erhalten().


1
Dies ist ein großes Duplikat von stackoverflow.com/questions/1102022/… und vielen, vielen anderen.
John Saunders

Antworten:


28

Um den Wert einer Aufzählung zu erhalten, müssen Sie die Aufzählung in den zugrunde liegenden Typ umwandeln:

Value = ((int)i).ToString();

Vielen Dank! Ich dachte darüber nach, dachte aber, dass es einen Weg geben könnte, es ohne Casting zu tun.
Lee D

87

Es ist schon eine Weile her, dass ich das tun musste, aber ich denke, das sollte funktionieren.

var directions = from Direction d in Enum.GetValues(typeof(Direction))
           select new { ID = (int)d, Name = d.ToString() };
return new SelectList(directions , "ID", "Name", someSelectedValue);

5
Funktioniert fast, braucht nur eine kleine Änderung! Ihr Code setzt den Wert auf Text, wenn das OP wollte, dass es eine Ganzzahl ist. Einfache Lösung. Wechseln Sie ID = dzu ID = (int)d. Danke, dass du das gepostet hast, ich hätte nie daran gedacht!
Chris

Gute Antwort, obwohl ich festgestellt habe, dass der Wert die Textdarstellung der Aufzählung und nicht die Ganzzahl sein muss, um das Dropdown-Menü vorab auszufüllen.
Luke Alderton


33

Das habe ich gerade gemacht und persönlich finde ich es 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();
        }

Ich werde irgendwann ein paar Übersetzungsarbeiten machen, damit Value = enu.ToString () irgendwo etwas aufruft.


1
Ich habe ein Problem mit diesem Code. Der "Wert" der SelectList entspricht dem "Text". Bei Verwendung von Enums mit EntityFramework muss der in der Datenbank gespeicherte Wert int sein.
Northstrider

Ok, dann mach das gut: Value = (int) enu
Dan

Der Grund, warum (int) enu im obigen Beispiel nicht funktioniert, ist, dass die Value-Eigenschaft von SelectListItem eine Zeichenfolge und keine Ganzzahl ist. ((int) enu) .ToString () funktioniert.
Teppic

Nein, wird es nicht. Im obigen Beispiel kennt es zur Kompilierungszeit den Typ von nicht T. Als solches kann man das nicht intmögen.
Ajbeaven

Ab C # 7.3 können Sie jetzt 'where T: System.Enum' hinzufügen.
Johan Maes

24

Ich wollte etwas tun, das Danns Lösung sehr ähnlich ist, aber ich brauchte den Wert als int und den Text als Zeichenfolgendarstellung der Aufzählung. Folgendes habe ich mir ausgedacht:

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

1
Dies ist bei weitem die bessere Antwort. Der Wert musste eine int-Darstellung von enum sein.
Fahad Abid Janjua

12

In ASP.NET Core MVC erfolgt dies mit Tag-Helfern .

<select asp-items="Html.GetEnumSelectList<Direction>()"></select>

Was ist mit dem Einstellen des ausgewählten Lasts?
JordanGW

Dann müssen Sie das asp-forAttribut angeben .
Fred

4

Vielleicht keine genaue Antwort auf die Frage, aber in CRUD-Szenarien implementiere ich normalerweise so etwas:

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 wird vor Ansicht ("Erstellen") und Ansicht ("Bearbeiten") aufgerufen, dann und in der Ansicht:

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

und das ist alles..


4

Oder:

foreach (string item in Enum.GetNames(typeof(MyEnum)))
{
    myDropDownList.Items.Add(new ListItem(item, ((int)((MyEnum)Enum.Parse(typeof(MyEnum), item))).ToString()));
}

4
return
            Enum
            .GetNames(typeof(ReceptionNumberType))
            .Where(i => (ReceptionNumberType)(Enum.Parse(typeof(ReceptionNumberType), i.ToString())) < ReceptionNumberType.MCI)
            .Select(i => new
            {
                description = i,
                value = (Enum.Parse(typeof(ReceptionNumberType), i.ToString()))
            });

3
    public static SelectList ToSelectList<TEnum>(this TEnum enumObj) where TEnum : struct
    {
        if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");

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

        return new SelectList(values, "ID", "Name", enumObj);
    }
    public static SelectList ToSelectList<TEnum>(this TEnum enumObj, string selectedValue) where TEnum : struct
    {
        if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");

        var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = (int)Enum.Parse(typeof(TEnum), e.ToString()), Name = e.ToString() };
        //var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = e, Name = e.ToString() };
        if (string.IsNullOrWhiteSpace(selectedValue))
        {
            return new SelectList(values, "ID", "Name", enumObj);
        }
        else
        {
            return new SelectList(values, "ID", "Name", selectedValue);
        }
    }

2

Ich habe aus verschiedenen Gründen mehr Klassen und Methoden:

Aufzählung zur Sammlung von Gegenständen

public static class EnumHelper
{
    public static List<ItemDto> EnumToCollection<T>()
    {
        return (Enum.GetValues(typeof(T)).Cast<int>().Select(
            e => new ItemViewModel
                     {
                         IntKey = e,
                         Value = Enum.GetName(typeof(T), e)
                     })).ToList();
    }
}

Auswahlliste in Controller erstellen

int selectedValue = 1; // resolved from anywhere
ViewBag.Currency = new SelectList(EnumHelper.EnumToCollection<Currency>(), "Key", "Value", selectedValue);

MyView.cshtml

@Html.DropDownListFor(x => x.Currency, null, htmlAttributes: new { @class = "form-control" })

2

Ich hatte viele Enum-Auswahllisten und stellte nach langem Jagen und Sieben fest, dass es für mich am besten war, einen generischen Helfer zu erstellen. Es gibt den Index oder Deskriptor als Selectlist-Wert und die Beschreibung als Selectlist-Text zurück:

Aufzählung:

public enum Your_Enum
{
    [Description("Description 1")]
    item_one,
    [Description("Description 2")]
    item_two
}

Helfer:

public static class Selectlists
{
    public static SelectList EnumSelectlist<TEnum>(bool indexed = false) where TEnum : struct
    {
        return new SelectList(Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(item => new SelectListItem
        {
            Text = GetEnumDescription(item as Enum),
            Value = indexed ? Convert.ToInt32(item).ToString() : item.ToString()
        }).ToList(), "Value", "Text");
    }

    // NOTE: returns Descriptor if there is no Description
    private static string GetEnumDescription(Enum value)
    {
        FieldInfo fi = value.GetType().GetField(value.ToString());
        DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
        if (attributes != null && attributes.Length > 0)
            return attributes[0].Description;
        else
            return value.ToString();
    }
}

Verwendung: Setzen Sie den Parameter für Indizes als Wert auf 'true':

var descriptorsAsValue = Selectlists.EnumSelectlist<Your_Enum>();
var indicesAsValue = Selectlists.EnumSelectlist<Your_Enum>(true);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.