[C#] Comment lier un Enum à un contrôle DropDownList dans ASP.NET?


Answers

Utilisez la classe d'utilitaires suivante Enumeration pour obtenir un IDictionary<int,string> (paire Enum value & name) d'une énumération ; Vous liez ensuite l' IDictionary à un contrôle pouvant être lié.

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

Exemple: Utilisation de la classe d'utilitaire pour lier des données d'énumération à un contrôle

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

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

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

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







Ma version est juste une forme compressée de ce qui précède:

foreach (Response r in Enum.GetValues(typeof(Response)))
{
    ListItem item = new ListItem(Enum.GetName(typeof(Response), r), r.ToString());
    DropDownList1.Items.Add(item);
}



Je ne suis pas sûr de savoir comment le faire dans ASP.NET, mais vérifiez this post ... il pourrait aider?

Enum.GetValues(typeof(Response));






Code générique utilisant la réponse six.

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

}



Après avoir lu tous les articles, j'ai trouvé une solution complète pour afficher la description enum dans la liste déroulante ainsi que la sélection de la valeur appropriée dans le menu déroulant Modèle en mode Édition:

enum:

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

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

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

Enum extension classe:

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

Classe de modèle:

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

et Voir:

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

et si vous utilisez cette liste déroulante sans vous lier à Model, vous pouvez l'utiliser à la place:

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

Donc, ce faisant, vous pouvez vous attendre à ce que votre liste déroulante affiche la description au lieu des valeurs enum. Aussi, quand il s'agit de modifier, votre modèle sera mis à jour par la valeur déroulante sélectionnée après la page de publication.




Vous pouvez également utiliser des méthodes d'extension. Pour ceux qui ne connaissent pas les extensions, je suggère de vérifier la documentation VB et C# .

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

Pour utiliser l'extension:

Imports <projectName>.CustomExtensions.ListItemCollectionExtension

...

yourDropDownList.Items.AddEnum(Of EnumType)()

C # Extension:

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 souhaitez définir l'élément sélectionné en même temps, 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 à System.Enum plutôt que la taille int et les problèmes de sortie sont évités. Par exemple 0xFFFF0000 serait 4294901760 comme uint mais serait -65536 comme un int.

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




Ceci est ma solution pour commander un Enum et DataBind (texte et valeur) à Dropdown en utilisant 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()));



C'est probablement une vieille question ... mais c'est comme ça que j'ai fait le mien.

Modèle:

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
}

Puis dans la vue: voici comment utiliser le menu déroulant.

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

Cela devrait peupler tout dans votre liste enum. J'espère que cela t'aides..




ASP.NET a depuis été mis à jour avec plus de fonctionnalités, et vous pouvez maintenant utiliser enum intégré à la liste déroulante.

Si vous voulez vous lier à l'Enum lui-même, utilisez ceci:

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

Si vous liez une instance de Response, utilisez ceci:

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



public enum Color
{
    RED,
    GREEN,
    BLUE
}

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