it-swarm-eu.dev

Wie binden Sie ein Enum an ein DropDownList-Steuerelement in ASP.NET?

Angenommen, ich habe die folgende einfache Aufzählung:

enum Response
{
    Yes = 1,
    No = 2,
    Maybe = 3
}

Wie kann ich diese Enumeration an ein DropDownList-Steuerelement binden, damit die Beschreibungen in der Liste angezeigt werden und der zugehörige numerische Wert (1,2,3) abgerufen wird, sobald eine Option ausgewählt wurde?

118
Ray Vega

Ich würde die Daten wahrscheinlich nicht binden, da es sich um eine Aufzählung handelt, und sie werden sich nach der Kompilierungszeit nicht ändern (es sei denn, ich habe eine dieser dummen Momente).

Besser einfach durch die Aufzählung iterieren:

Dim itemValues As Array = System.Enum.GetValues(GetType(Response))
Dim itemNames As Array = System.Enum.GetNames(GetType(Response))

For i As Integer = 0 To itemNames.Length - 1
    Dim item As New ListItem(itemNames(i), itemValues(i))
    dropdownlist.Items.Add(item)
Next

Oder das Gleiche in C #

Array itemValues = System.Enum.GetValues(typeof(Response));
Array itemNames = System.Enum.GetNames(typeof(Response));

for (int i = 0; i <= itemNames.Length - 1 ; i++) {
    ListItem item = new ListItem(itemNames[i], itemValues[i]);
    dropdownlist.Items.Add(item);
}
107
Mark Glorie

Verwenden Sie die folgende Utility-Klasse Enumeration, um ein IDictionary<int,string> (Aufzählungswert & Namenspaar) aus einem Aufzählung; Anschließend binden Sie das IDictionary an ein bindbares Steuerelement.

public static class Enumeration
{
    public static IDictionary<int, string> GetAll<TEnum>() where TEnum: struct
    {
        var enumerationType = typeof (TEnum);

        if (!enumerationType.IsEnum)
            throw new ArgumentException("Enumeration type is expected.");

        var dictionary = new Dictionary<int, string>();

        foreach (int value in Enum.GetValues(enumerationType))
        {
            var name = Enum.GetName(enumerationType, value);
            dictionary.Add(value, name);
        }

        return dictionary;
    }
}

Beispiel: Verwenden der Utility-Klasse zum Binden von Aufzählungsdaten an ein Steuerelement

ddlResponse.DataSource = Enumeration.GetAll<Response>();
ddlResponse.DataTextField = "Value";
ddlResponse.DataValueField = "Key";
ddlResponse.DataBind();
69
Leyu

Ich benutze dies für ASP.NET MVC:

Html.DropDownListFor(o => o.EnumProperty, Enum.GetValues(typeof(enumtype)).Cast<enumtype>().Select(x => new SelectListItem { Text = x.ToString(), Value = ((int)x).ToString() }))
40
Feryt

Meine Version ist nur eine komprimierte Form der oben genannten:

foreach (Response r in Enum.GetValues(typeof(Response)))
{
    ListItem item = new ListItem(Enum.GetName(typeof(Response), r), r.ToString());
    DropDownList1.Items.Add(item);
}
35
VanOrman
public enum Color
{
    RED,
    GREEN,
    BLUE
}

Jeder Aufzählungstyp leitet sich von System.Enum ab. Es gibt zwei statische Methoden, mit denen Sie Daten an ein Dropdown-Listensteuerelement binden (und den Wert abrufen) können. Dies sind Enum.GetNames und Enum.Parse. Mit GetNames können Sie wie folgt an Ihr Dropdown-Listensteuerelement binden:

protected System.Web.UI.WebControls.DropDownList ddColor;

private void Page_Load(object sender, System.EventArgs e)
{
     if(!IsPostBack)
     {
        ddColor.DataSource = Enum.GetNames(typeof(Color));
        ddColor.DataBind();
     }
}

Nun, wenn Sie den Enum-Wert Back on Selection möchten ...

  private void ddColor_SelectedIndexChanged(object sender, System.EventArgs e)
  {
    Color selectedColor = (Color)Enum.Parse(typeof(Color),ddColor.SelectedValue
  }
22
user

Nachdem ich alle Beiträge gelesen hatte, stellte ich eine umfassende Lösung zur Unterstützung der Anzeige der Enum-Beschreibung in der Dropdown-Liste sowie zur Auswahl des richtigen Werts aus Modell in der Dropdown-Liste bei der Anzeige im Bearbeitungsmodus vor:

aufzählung:

using System.ComponentModel;
public enum CompanyType
{
    [Description("")]
    Null = 1,

    [Description("Supplier")]
    Supplier = 2,

    [Description("Customer")]
    Customer = 3
}

enum extension class:

using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web.Mvc;

public static class EnumExtension
{
    public static string ToDescription(this System.Enum value)
    {
        var attributes = (DescriptionAttribute[])value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
        return attributes.Length > 0 ? attributes[0].Description : value.ToString();
    }

    public static IEnumerable<SelectListItem> ToSelectList<T>(this System.Enum enumValue)
    {
        return
            System.Enum.GetValues(enumValue.GetType()).Cast<T>()
                  .Select(
                      x =>
                      new SelectListItem
                          {
                              Text = ((System.Enum)(object) x).ToDescription(),
                              Value = x.ToString(),
                              Selected = (enumValue.Equals(x))
                          });
    }
}

Modellklasse:

public class Company
{
    public string CompanyName { get; set; }
    public CompanyType Type { get; set; }
}

und Ansicht:

@Html.DropDownListFor(m => m.Type,
@Model.Type.ToSelectList<CompanyType>())

wenn Sie dieses Dropdown-Menü ohne Bindung an Model verwenden, können Sie stattdessen Folgendes verwenden:

@Html.DropDownList("type",                  
Enum.GetValues(typeof(CompanyType)).Cast<CompanyType>()
.Select(x => new SelectListItem {Text = x.ToDescription(), Value = x.ToString()}))

Wenn Sie dies tun, können Sie erwarten, dass in der Dropdown-Liste "Beschreibung" anstelle von Enum-Werten angezeigt wird. Auch beim Bearbeiten wird Ihr Modell nach dem Posten der Seite durch das Aufklappen des ausgewählten Werts aktualisiert.

10
Amir Chatrbahr

Wie andere bereits gesagt haben - binden Sie keine Daten an eine Aufzählung, es sei denn, Sie müssen sich je nach Situation an verschiedene Aufzählungen binden. Es gibt verschiedene Möglichkeiten, dies zu tun. Nachfolgend einige Beispiele.

ObjectDataSource

Eine deklarative Methode, um dies mit ObjectDataSource zu tun. Erstellen Sie zunächst eine BusinessObject-Klasse, die die List zurückgibt, um die DropDownList an Folgendes zu binden:

public class DropDownData
{
    enum Responses { Yes = 1, No = 2, Maybe = 3 }

    public String Text { get; set; }
    public int Value { get; set; }

    public List<DropDownData> GetList()
    {
        var items = new List<DropDownData>();
        foreach (int value in Enum.GetValues(typeof(Responses)))
        {
            items.Add(new DropDownData
                          {
                              Text = Enum.GetName(typeof (Responses), value),
                              Value = value
                          });
        }
        return items;
    }
}

Fügen Sie dann der ASPX-Seite ein HTML-Markup hinzu, um auf diese BO-Klasse zu verweisen:

<asp:DropDownList ID="DropDownList1" runat="server" 
    DataSourceID="ObjectDataSource1" DataTextField="Text" DataValueField="Value">
</asp:DropDownList>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
    SelectMethod="GetList" TypeName="DropDownData"></asp:ObjectDataSource>

Diese Option erfordert keinen Code dahinter.

Code hinter DataBind

So minimieren Sie den HTML-Code in der ASPX-Seite und binden Code Behind ein:

enum Responses { Yes = 1, No = 2, Maybe = 3 }

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        foreach (int value in Enum.GetValues(typeof(Responses)))
        {
            DropDownList1.Items.Add(new ListItem(Enum.GetName(typeof(Responses), value), value.ToString()));
        }
    }
}

Auf jeden Fall besteht der Trick darin, die Enum-Typ-Methoden von GetValues, GetNames usw. für Sie arbeiten zu lassen.

8
Johan Danforth

Ich bin mir nicht sicher, wie ich es in ASP.NET machen soll, aber check out this post ... könnte es helfen?

Enum.GetValues(typeof(Response));
6
rudigrobler
Array itemValues = Enum.GetValues(typeof(TaskStatus));
Array itemNames = Enum.GetNames(typeof(TaskStatus));

for (int i = 0; i <= itemNames.Length; i++)
{
    ListItem item = new ListItem(itemNames.GetValue(i).ToString(),
    itemValues.GetValue(i).ToString());
    ddlStatus.Items.Add(item);
}
5
Adarsh

Du könntest linq benutzen:

var responseTypes= Enum.GetNames(typeof(Response)).Select(x => new { text = x, value = (int)Enum.Parse(typeof(Response), x) });
    DropDownList.DataSource = responseTypes;
    DropDownList.DataTextField = "text";
    DropDownList.DataValueField = "value";
    DropDownList.DataBind();
5
KrishnaDhungana
public enum Color
{
    RED,
    GREEN,
    BLUE
}

ddColor.DataSource = Enum.GetNames(typeof(Color));
ddColor.DataBind();
4
sankalp gurha

Nachdem ich diese Antwort gefunden hatte, kam ich auf eine meiner Meinung nach bessere (zumindest elegantere) Art und Weise, dies zu tun, und dachte, ich käme zurück und teile es hier.

PageLoad:

DropDownList1.DataSource = Enum.GetValues(typeof(Response));
DropDownList1.DataBind();

LoadValues:

Response rIn = Response.Maybe;
DropDownList1.Text = rIn.ToString();

SaveValues:

Response rOut = (Response) Enum.Parse(typeof(Response), DropDownList1.Text);
3
Ben Hughes

Allgemeiner Code mit Antwort sechs.

public static void BindControlToEnum(DataBoundControl ControlToBind, Type type)
{
    //ListControl

    if (type == null)
        throw new ArgumentNullException("type");
    else if (ControlToBind==null )
        throw new ArgumentNullException("ControlToBind");
    if (!type.IsEnum)
        throw new ArgumentException("Only enumeration type is expected.");

    Dictionary<int, string> pairs = new Dictionary<int, string>();

    foreach (int i in Enum.GetValues(type))
    {
        pairs.Add(i, Enum.GetName(type, i));
    }
    ControlToBind.DataSource = pairs;
    ListControl lstControl = ControlToBind as ListControl;
    if (lstControl != null)
    {
        lstControl.DataTextField = "Value";
        lstControl.DataValueField = "Key";
    }
    ControlToBind.DataBind();

}
3
Muhammed Qasim

Dies ist wahrscheinlich eine alte Frage. Aber so habe ich meine gemacht.

Modell:

public class YourEntity
{
   public int ID { get; set; }
   public string Name{ get; set; }
   public string Description { get; set; }
   public OptionType Types { get; set; }
}

public enum OptionType
{
    Unknown,
    Option1, 
    Option2,
    Option3
}

Dann in der Ansicht: Hier erfahren Sie, wie Sie das Dropdown-Menü ausfüllen.

@Html.EnumDropDownListFor(model => model.Types, htmlAttributes: new { @class = "form-control" })

Dies sollte alles in Ihrer Aufzählungsliste ausfüllen. Hoffe das hilft..

2
Marie McDonley

Das ist nicht ganz das, wonach Sie suchen, könnte aber helfen:

http://blog.jeffhandley.com/archive/2008/01/27/enum-list-dropdown-control.aspx

1
roman m

ASP.NET wurde seitdem mit einigen weiteren Funktionen aktualisiert, und Sie können jetzt die integrierte Aufzählung zum Dropdown verwenden.

Wenn Sie die Enumeration selbst binden möchten, verwenden Sie Folgendes:

@Html.DropDownList("response", EnumHelper.GetSelectList(typeof(Response)))

Wenn Sie eine Instanz von Response binden, verwenden Sie Folgendes:

// Assuming Model.Response is an instance of Response
@Html.EnumDropDownListFor(m => m.Response)
1
bradlis7

Warum nicht so benutzen, um jede listControle übergeben zu können:


public static void BindToEnum(Type enumType, ListControl lc)
        {
            // get the names from the enumeration
            string[] names = Enum.GetNames(enumType);
            // get the values from the enumeration
            Array values = Enum.GetValues(enumType);
            // turn it into a hash table
            Hashtable ht = new Hashtable();
            for (int i = 0; i < names.Length; i++)
                // note the cast to integer here is important
                // otherwise we'll just get the enum string back again
                ht.Add(names[i], (int)values.GetValue(i));
            // return the dictionary to be bound to
            lc.DataSource = ht;
            lc.DataTextField = "Key";
            lc.DataValueField = "Value";
            lc.DataBind();
        }

BindToEnum(typeof(NewsType), DropDownList1);
BindToEnum(typeof(NewsType), CheckBoxList1);
BindToEnum(typeof(NewsType), RadoBuuttonList1);
1
Mostafa

Wenn Sie eine benutzerfreundlichere Beschreibung in Ihrem Kombinationsfeld (oder einem anderen Steuerelement) haben möchten, können Sie das Description-Attribut mit der folgenden Funktion verwenden:

    public static object GetEnumDescriptions(Type enumType)
    {
        var list = new List<KeyValuePair<Enum, string>>();
        foreach (Enum value in Enum.GetValues(enumType))
        {
            string description = value.ToString();
            FieldInfo fieldInfo = value.GetType().GetField(description);
            var attribute = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false).First();
            if (attribute != null)
            {
                description = (attribute as DescriptionAttribute).Description;
            }
            list.Add(new KeyValuePair<Enum, string>(value, description));
        }
        return list;
    }

Hier ist ein Beispiel für eine Aufzählung mit angewendeten Beschreibungsattributen:

    enum SampleEnum
    {
        NormalNoSpaces,
        [Description("Description With Spaces")]
        DescriptionWithSpaces,
        [Description("50%")]
        Percent_50,
    }

Dann binde an die Steuerung wie folgt ...

        m_Combo_Sample.DataSource = GetEnumDescriptions(typeof(SampleEnum));
        m_Combo_Sample.DisplayMember = "Value";
        m_Combo_Sample.ValueMember = "Key";

Auf diese Weise können Sie beliebigen Text in die Dropdown-Liste einfügen, ohne dass dieser wie ein Variablenname aussehen muss

0
Josh Stribling

Tutorial für asp.net und winforms mit Combobox und Dropdown-Liste: Verwendung von Enum mit Combobox in C # WinForms und Asp.Net

hoffnung hilft

0
justin

Lesen Sie meinen Beitrag zum Erstellen eines benutzerdefinierten Hilfsprogramms "ASP.NET MVC - Erstellen eines DropDownList-Hilfsprogramms für Aufzählungen": http://blogs.msdn.com/b/stuartleeks/archive/2010/05/21/asp -net-mvc-create-a-dropdownlist-helper-for-enums.aspx

0
Stuart Leeks

Dies ist meine Lösung für das Bestellen einer Aufzählung und von DataBind (Text und Wert) zu Dropdown unter Verwendung von LINQ

var mylist = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().ToList<MyEnum>().OrderBy(l => l.ToString());
foreach (MyEnum item in mylist)
    ddlDivisao.Items.Add(new ListItem(item.ToString(), ((int)item).ToString()));
0
Diego Mendes

Die akzeptierte Lösung funktioniert nicht, aber der folgende Code hilft anderen bei der Suche nach der kürzesten Lösung.

 foreach (string value in Enum.GetNames(typeof(Response)))
                    ddlResponse.Items.Add(new ListItem()
                    {
                        Text = value,
                        Value = ((int)Enum.Parse(typeof(Response), value)).ToString()
                    });
0
Hakan Erdogan

Sie können auch Erweiterungsmethoden verwenden. Für diejenigen, die nicht mit Erweiterungen vertraut sind, empfehle ich, die Dokumentation VB und C # zu lesen.


VB Extension:

Namespace CustomExtensions
    Public Module ListItemCollectionExtension

        <Runtime.CompilerServices.Extension()> _
        Public Sub AddEnum(Of TEnum As Structure)(items As System.Web.UI.WebControls.ListItemCollection)
            Dim enumerationType As System.Type = GetType(TEnum)
            Dim enumUnderType As System.Type = System.Enum.GetUnderlyingType(enumType)

            If Not enumerationType.IsEnum Then Throw New ArgumentException("Enumeration type is expected.")

            Dim enumTypeNames() As String = System.Enum.GetNames(enumerationType)
            Dim enumTypeValues() As TEnum = System.Enum.GetValues(enumerationType)

            For i = 0 To enumTypeNames.Length - 1
                items.Add(New System.Web.UI.WebControls.ListItem(saveResponseTypeNames(i), TryCast(enumTypeValues(i), System.Enum).ToString("d")))
            Next
        End Sub
    End Module
End Namespace

So verwenden Sie die Erweiterung:

Imports <projectName>.CustomExtensions.ListItemCollectionExtension

...

yourDropDownList.Items.AddEnum(Of EnumType)()

C # -Erweiterung:

namespace CustomExtensions
{
    public static class ListItemCollectionExtension
    {
        public static void AddEnum<TEnum>(this System.Web.UI.WebControls.ListItemCollection items) where TEnum : struct
        {
            System.Type enumType = typeof(TEnum);
            System.Type enumUnderType = System.Enum.GetUnderlyingType(enumType);

            if (!enumType.IsEnum) throw new Exception("Enumeration type is expected.");

            string[] enumTypeNames = System.Enum.GetNames(enumType);
            TEnum[] enumTypeValues = (TEnum[])System.Enum.GetValues(enumType);

            for (int i = 0; i < enumTypeValues.Length; i++)
            {
                items.add(new System.Web.UI.WebControls.ListItem(enumTypeNames[i], (enumTypeValues[i] as System.Enum).ToString("d")));
            }
        }
    }
}

So verwenden Sie die Erweiterung:

using CustomExtensions.ListItemCollectionExtension;

...

yourDropDownList.Items.AddEnum<EnumType>()

Wenn Sie das ausgewählte Element gleichzeitig einstellen möchten, ersetzen Sie es

items.Add(New System.Web.UI.WebControls.ListItem(saveResponseTypeNames(i), saveResponseTypeValues(i).ToString("d")))

mit

Dim newListItem As System.Web.UI.WebControls.ListItem
newListItem = New System.Web.UI.WebControls.ListItem(enumTypeNames(i), Convert.ChangeType(enumTypeValues(i), enumUnderType).ToString())
newListItem.Selected = If(EqualityComparer(Of TEnum).Default.Equals(selected, saveResponseTypeValues(i)), True, False)
items.Add(newListItem)

Durch die Konvertierung in System.Enum werden Probleme mit der int-Größe und der Ausgabe vermieden. Zum Beispiel wäre 0xFFFF0000 4294901760 als uint, aber -65536 als int.

TryCast und as System.Enum sind etwas schneller als Convert.ChangeType (enumTypeValues ​​[i], enumUnderType) .ToString () (12:13 in meinen Geschwindigkeitstests).

0
Trisped