138 votes

Comment lier une Enum à un contrôle DropDownList en ASP.NET ?

Disons que j'ai l'énumération simple suivante :

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

Comment puis-je lier cet enum à un contrôle DropDownList afin que les descriptions soient affichées dans la liste et que la valeur numérique associée (1, 2, 3) soit récupérée une fois qu'une option a été sélectionnée ?

0voto

Sheo Narayan Points 31

Pour une raison quelconque, la réponse fournie par Mark Glorie n'a pas fonctionné pour moi. Comme le GetValues renvoie un objet Array et que je ne pouvais pas utiliser l'indexeur pour obtenir la valeur des éléments. J'ai essayé itemsValue.GetValue(i) et cela a fonctionné mais malheureusement, cela n'a pas rempli la valeur de l'énumération dans la valeur de l'élément de la liste déroulante. Le nom de l'élément de l'énumération est simplement inséré dans le texte et la valeur de la liste déroulante.

J'ai modifié le code de Mark et l'ai posté comme solution ici. Comment lier une Enum avec sa valeur à la DropDownList en ASP.NET ?

J'espère que cela vous aidera.

Merci

0voto

Stuart Leeks Points 201

Consultez mon article sur la création d'une aide personnalisée "ASP.NET MVC - Creating a DropDownList helper for enums" : http://blogs.msdn.com/b/stuartleeks/archive/2010/05/21/asp-net-mvc-creating-a-dropdownlist-helper-for-enums.aspx

0voto

Josh Stribling Points 423

Si vous souhaitez avoir une description plus conviviale dans votre boîte combinée (ou autre contrôle), vous pouvez utiliser l'attribut Description avec la fonction suivante :

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

Voici un exemple d'un enum avec des attributs Description appliqués :

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

Puis lier au contrôle comme ça...

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

De cette façon, vous pouvez mettre le texte que vous voulez dans la liste déroulante sans que cela ressemble à un nom de variable.

0voto

Trisped Points 2571

Vous pouvez également utiliser les méthodes d'extension. Pour ceux qui ne sont pas familiers avec les extensions, je vous suggère de consulter la section VB y C# documentation.


Extension VB :

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

Pour utiliser l'extension :

Imports <projectName>.CustomExtensions.ListItemCollectionExtension

...

yourDropDownList.Items.AddEnum(Of EnumType)()

Extension C# :

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

Pour utiliser l'extension :

using CustomExtensions.ListItemCollectionExtension;

...

yourDropDownList.Items.AddEnum<EnumType>()

Si vous voulez régler l'élément sélectionné en même temps que vous remplacez

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

avec

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)

En convertissant en System.Enum plutôt qu'en int, on évite les problèmes de taille et de sortie. Par exemple, 0xFFFF0000 serait 4294901760 en tant que uint mais serait -65536 en tant que int.

TryCast et comme System.Enum sont légèrement plus rapides que Convert.ChangeType(enumTypeValues[i], enumUnderType).ToString() (12:13 dans mes tests de vitesse).

0voto

Hakan Erdogan Points 199

La solution acceptée ne fonctionne pas, mais le code ci-dessous aidera ceux qui cherchent la solution la plus courte.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X