web-dev-qa-db-fra.com

Liaison d'une énumération à une zone de liste déroulante WinForms, puis définition

beaucoup de gens ont répondu à la question de savoir comment lier une énumération à une liste déroulante dans WinForms. C'est comme ça:

comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));

Mais cela est plutôt inutile sans pouvoir définir la valeur réelle à afficher.

J'ai essayé:

comboBox1.SelectedItem = MyEnum.Something; // Does not work. SelectedItem remains null

J'ai aussi essayé:

comboBox1.SelectedIndex = Convert.ToInt32(MyEnum.Something); // ArgumentOutOfRangeException, SelectedIndex remains -1

Est-ce que quelqu'un a des idées pour faire ça?

102
Tony Miletto

L'énum

public enum Status { Active = 0, Canceled = 3 }; 

Définir les valeurs déroulantes

cbStatus.DataSource = Enum.GetValues(typeof(Status));

Obtenir l'énumération de l'élément sélectionné

Status status; 
Enum.TryParse<Status>(cbStatus.SelectedValue.ToString(), out status); 
137
Amir Shenouda

Pour simplifier:

Commencez par initialiser cette commande: (par exemple après InitalizeComponent())

yourComboBox.DataSource =  Enum.GetValues(typeof(YourEnum));

Pour récupérer l’élément sélectionné dans la liste déroulante:

YourEnum enum = (YourEnum) yourComboBox.SelectedItem;

Si vous souhaitez définir une valeur pour la liste déroulante: 

yourComboBox.SelectedItem = YourEnem.Foo;
17
dr.Crow

Le code

comboBox1.SelectedItem = MyEnum.Something;

est ok, le problème doit résider dans le DataBinding. Les affectations DataBinding ont lieu après le constructeur, principalement la première fois que la liste déroulante est affichée. Essayez de définir la valeur dans l'événement Load. Par exemple, ajoutez ce code:

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    comboBox1.SelectedItem = MyEnum.Something;
}

Et vérifiez si cela fonctionne.

14
jmservera

Disons que vous avez l'énumération suivante

public enum Numbers {Zero = 0, One, Two};

Vous devez avoir une structure pour mapper ces valeurs à une chaîne:

public struct EntityName
{
    public Numbers _num;
    public string _caption;

    public EntityName(Numbers type, string caption)
    {
        _num = type;
        _caption = caption;
    }

    public Numbers GetNumber() 
    {
        return _num;
    }

    public override string ToString()
    {
        return _caption;
    }
}

Maintenant, retournez un tableau d'objets avec tous les enums mappés à une chaîne:

public object[] GetNumberNameRange()
{
    return new object[]
    {
        new EntityName(Number.Zero, "Zero is chosen"),
        new EntityName(Number.One, "One is chosen"),
        new EntityName(Number.Two, "Two is chosen")
    };
}

Et utilisez ce qui suit pour remplir votre liste déroulante:

ComboBox numberCB = new ComboBox();
numberCB.Items.AddRange(GetNumberNameRange());

Créez une fonction pour récupérer le type enum au cas où vous voudriez le passer à une fonction

public Numbers GetConversionType() 
{
    EntityName type = (EntityName)numberComboBox.SelectedItem;
    return type.GetNumber();           
}

et alors vous devriez être ok :)

11
ncoder83

Essayer:

comboBox1.SelectedItem = MyEnum.Something;

EDITS:

Oups, vous avez déjà essayé cela. Cependant, cela a fonctionné pour moi lorsque ma comboBox était définie pour être une DropDownList. 

Voici mon code complet qui fonctionne pour moi (avec DropDown et DropDownList):

public partial class Form1 : Form
{
    public enum BlahEnum
    { 
        Red,
        Green,
        Blue,
        Purple
    }

    public Form1()
    {
        InitializeComponent();

        comboBox1.DataSource = Enum.GetValues(typeof(BlahEnum));

    }

    private void button1_Click(object sender, EventArgs e)
    {
        comboBox1.SelectedItem = BlahEnum.Blue;
    }
}
11
rein

Essaye ça:

// fill list
MyEnumDropDownList.DataSource = Enum.GetValues(typeof(MyEnum));

// binding
MyEnumDropDownList.DataBindings.Add(new Binding("SelectedValue", StoreObject, "StoreObjectMyEnumField"));

StoreObject est mon exemple d'objet avec la propriété StoreObjectMyEnumField pour la valeur de magasin MyEnum.

4
Pavel Šubík

c’est la solutionpour charger un élément d’énumération dans une liste déroulante:

comboBox1.Items.AddRange( Enum.GetNames(typeof(Border3DStyle)));

Et utilisez ensuite l'énumération en tant que texte:

toolStripStatusLabel1.BorderStyle = (Border3DStyle)Enum.Parse(typeof(Border3DStyle),comboBox1.Text);
3
Haider Ali Wajihi

Basé sur la réponse de @Amir Shenouda, je me retrouve avec ceci:

Définition de l'énum:

public enum Status { Active = 0, Canceled = 3 }; 

Définir les valeurs de la liste déroulante:

cbStatus.DataSource = Enum.GetValues(typeof(Status));

Obtenir l'énumération de l'élément sélectionné:

Status? status = cbStatus.SelectedValue as Status?;
3
Tarc
 public static void FillByEnumOrderByNumber<TEnum>(this System.Windows.Forms.ListControl ctrl, TEnum enum1, bool showValueInDisplay = true) where TEnum : struct
    {
        if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");

        var values = from TEnum enumValue in Enum.GetValues(typeof(TEnum))
                     select
                        new
                         KeyValuePair<TEnum, string>(   (enumValue), enumValue.ToString());

        ctrl.DataSource = values
            .OrderBy(x => x.Key)

            .ToList();

        ctrl.DisplayMember = "Value";
        ctrl.ValueMember = "Key";

        ctrl.SelectedValue = enum1;
    }
    public static void  FillByEnumOrderByName<TEnum>(this System.Windows.Forms.ListControl ctrl, TEnum enum1, bool showValueInDisplay = true  ) where TEnum : struct
    {
        if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");

        var values = from TEnum enumValue in Enum.GetValues(typeof(TEnum))
                     select 
                        new 
                         KeyValuePair<TEnum,string> ( (enumValue),  enumValue.ToString()  );

        ctrl.DataSource = values
            .OrderBy(x=>x.Value)
            .ToList();

        ctrl.DisplayMember = "Value";
        ctrl.ValueMember = "Key";

        ctrl.SelectedValue = enum1;
    }
3
Mickey Perlstein
    public enum Colors
    {
        Red = 10,
        Blue = 20,
        Green = 30,
        Yellow = 40,
    }

comboBox1.DataSource = Enum.GetValues(typeof(Colors));

Full Source ... Relier une énumération à Combobox

2
caronjudith
public Form1()
{
    InitializeComponent();
    comboBox.DataSource = EnumWithName<SearchType>.ParseEnum();
    comboBox.DisplayMember = "Name";
}

public class EnumWithName<T>
{
    public string Name { get; set; }
    public T Value { get; set; }

    public static EnumWithName<T>[] ParseEnum()
    {
        List<EnumWithName<T>> list = new List<EnumWithName<T>>();

        foreach (object o in Enum.GetValues(typeof(T)))
        {
            list.Add(new EnumWithName<T>
            {
                Name = Enum.GetName(typeof(T), o).Replace('_', ' '),
                Value = (T)o
            });
        }

        return list.ToArray();
    }
}

public enum SearchType
{
    Value_1,
    Value_2
}
2
Proteux

Convertit l'énumération en une liste de chaînes et l'ajoute à la comboBox

comboBox1.DataSource = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();

Définir la valeur affichée à l'aide de selectedItem

comboBox1.SelectedItem = SomeEnum.SomeValue;
1
Stijn Bollen

J'utilise la méthode d'assistance suivante, que vous pouvez lier à votre liste.

    ''' <summary>
    ''' Returns enumeration as a sortable list.
    ''' </summary>
    ''' <param name="t">GetType(some enumeration)</param>
    Public Shared Function GetEnumAsList(ByVal t As Type) As SortedList(Of String, Integer)

        If Not t.IsEnum Then
            Throw New ArgumentException("Type is not an enumeration.")
        End If

        Dim items As New SortedList(Of String, Integer)
        Dim enumValues As Integer() = [Enum].GetValues(t)
        Dim enumNames As String() = [Enum].GetNames(t)

        For i As Integer = 0 To enumValues.GetUpperBound(0)
            items.Add(enumNames(i), enumValues(i))
        Next

        Return items

    End Function
1
ScottE

Rien de tout cela n'a fonctionné pour moi, mais cela a fonctionné (et cela a eu l'avantage supplémentaire de pouvoir avoir une meilleure description du nom de chaque enum). Je ne sais pas si cela est dû aux mises à jour .net ou non, mais peu importe, je pense que c'est la meilleure façon. Vous devrez ajouter une référence à:

using System.ComponentModel;

enum MyEnum
{
    [Description("Red Color")]
    Red = 10,
    [Description("Blue Color")]
    Blue = 50
}

....

    private void LoadCombobox()
    {
        cmbxNewBox.DataSource = Enum.GetValues(typeof(MyEnum))
            .Cast<Enum>()
            .Select(value => new
            {
                (Attribute.GetCustomAttribute(value.GetType().GetField(value.ToString()), typeof(DescriptionAttribute)) as DescriptionAttribute).Description,
                value
            })
            .OrderBy(item => item.value)
            .ToList();
        cmbxNewBox.DisplayMember = "Description";
        cmbxNewBox.ValueMember = "value";
    }

Ensuite, lorsque vous souhaitez accéder aux données, utilisez ces deux lignes:

        Enum.TryParse<MyEnum>(cmbxNewBox.SelectedValue.ToString(), out MyEnum proc);
        int nValue = (int)proc;
0
DaBlue

Méthode générique pour définir une énumération comme source de données pour les menus déroulants

L'affichage serait name . La valeur sélectionnée serait Enum elle-même

public IList<KeyValuePair<string, T>> GetDataSourceFromEnum<T>() where T : struct,IConvertible
    {
        IList<KeyValuePair<string, T>> list = new BindingList<KeyValuePair<string, T>>();
        foreach (string value in Enum.GetNames(typeof(T)))
        {
            list.Add(new KeyValuePair<string, T>(value, (T)Enum.Parse(typeof(T), value)));
        }
        return list;
    }
0
Rahul

Pour le moment, j'utilise la propriété Items plutôt que la source de données, cela signifie que je dois appeler Add pour chaque valeur enum, mais que c'est une petite enum et son code temporaire de toute façon.

Ensuite, je peux simplement faire le Convert.ToInt32 sur la valeur et le définir avec SelectedIndex.

Solution temporaire, mais YAGNI pour le moment.

Vive les idées, je les utiliserai probablement lorsque je rédigerai la version appropriée après avoir reçu un retour des clients.

0
Tony Miletto

Dans Framework 4, vous pouvez utiliser le code suivant:

Pour lier MultiColumnMode enum à une liste déroulante, par exemple:

cbMultiColumnMode.Properties.Items.AddRange(typeof(MultiColumnMode).GetEnumNames());

et pour obtenir l'index sélectionné:

MultiColumnMode multiColMode = (MultiColumnMode)cbMultiColumnMode.SelectedIndex;

note: J'utilise la liste déroulante DevExpress dans cet exemple, vous pouvez faire de même dans la liste déroulante Win Form

0
Sherif Hassaneen

utilisez uniquement le casting de cette façon:

if((YouEnum)ComboBoxControl.SelectedItem == YouEnum.Español)
{
   //TODO: type you code here
}
0
Victor Gomez

Vieille question peut-être ici mais j'avais le problème et la solution était simple et facile, j'ai trouvé ceci http://www.c-sharpcorner.com/UploadFile/mahesh/1220/

Il utilise la chaîne de données et fonctionne bien, alors vérifiez-le. 

0
Johan

C’était toujours un problème ... si vous avez un Enum trié, comme de 0 à ...

public enum Test
      one
      Two
      Three
 End

vous pouvez lier des noms à une liste déroulante et au lieu d'utiliser la propriété .SelectedValue, utilisez .SelectedIndex

   Combobox.DataSource = System.Enum.GetNames(GetType(test))

et le

Dim x as byte = 0
Combobox.Selectedindex=x
0
Farhad

Vous pouvez utiliser les fonctions "FindString ..":

Public Class Form1
    Public Enum Test
        pete
        jack
        fran
        bill
    End Enum
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ComboBox1.DataSource = [Enum].GetValues(GetType(Test))
        ComboBox1.SelectedIndex = ComboBox1.FindStringExact("jack")
        ComboBox1.SelectedIndex = ComboBox1.FindStringExact(Test.jack.ToString())
        ComboBox1.SelectedIndex = ComboBox1.FindStringExact([Enum].GetName(GetType(Test), Test.jack))
        ComboBox1.SelectedItem = Test.bill
    End Sub
End Class
0
Abe Lincoln
comboBox1.SelectedItem = MyEnum.Something;

devrait bien fonctionner ... Comment pouvez-vous dire que SelectedItem est null?

0
bruno conde

Vous pouvez utiliser une méthode d'extension

 public static void EnumForComboBox(this ComboBox comboBox, Type enumType)
 {
     var memInfo = enumType.GetMembers().Where(a => a.MemberType == MemberTypes.Field).ToList();
     comboBox.Items.Clear();
     foreach (var member in memInfo)
     {
         var myAttributes = member.GetCustomAttribute(typeof(DescriptionAttribute), false);
         var description = (DescriptionAttribute)myAttributes;
         if (description != null)
         {
             if (!string.IsNullOrEmpty(description.Description))
             {
                 comboBox.Items.Add(description.Description);
                 comboBox.SelectedIndex = 0;
                 comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
             }
         }   
     }
 }

Comment utiliser ... Declare enum 

using System.ComponentModel;

public enum CalculationType
{
    [Desciption("LoaderGroup")]
    LoaderGroup,
    [Description("LadingValue")]
    LadingValue,
    [Description("PerBill")]
    PerBill
}

Cette méthode affiche la description dans les éléments de la liste déroulante.

combobox1.EnumForComboBox(typeof(CalculationType));
0
Morteza Najafian

Vous pouvez utiliser une liste de valeurs KeyValuePair comme source de données pour la liste déroulante. Vous aurez besoin d'une méthode d'assistance dans laquelle vous pouvez spécifier le type enum. Elle renvoie IEnumerable> où int est la valeur de enum et string est le nom de la valeur enum. Dans votre liste déroulante, définissez la propriété DisplayMember sur 'Key' et la propriété ValueMember sur 'Value'. Value et Key sont des propriétés publiques de la structure KeyValuePair. Ensuite, lorsque vous définissez la propriété SelectedItem sur une valeur enum comme vous le faites, cela devrait fonctionner.

0
Mehmet Aras

Un peu tard pour cette soirée, 

La méthode SelectedValue.ToString () doit extraire le DisplayedName. Cependant, cet article DataBinding Enum et With With Descriptions est un moyen pratique non seulement de l’avoir, mais vous pouvez également ajouter un attribut de description personnalisé à l’énum et l’utiliser comme valeur affichée si vous préférez. Très simple et facile et environ 15 lignes de code (sauf si vous comptez les accolades) pour tout.

C'est un code assez astucieux et vous pouvez en faire une méthode d'extension pour démarrer ... 

0
Stix
comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));

comboBox1.SelectedIndex = (int)MyEnum.Something;

comboBox1.SelectedIndex = Convert.ToInt32(MyEnum.Something);

Ces deux fonctionnent pour moi, êtes-vous sûr qu'il n'y a pas autre chose qui ne va pas?

0

Cela ne sera probablement jamais vu parmi toutes les autres réponses, mais c'est le code que j'ai proposé, cela présente l'avantage d'utiliser le DescriptionAttribute s'il existe, mais sinon, utiliser le nom de la valeur enum elle-même. .

J'ai utilisé un dictionnaire car il possède un modèle d'éléments clé/valeur prêt à l'emploi. Un List<KeyValuePair<string,object>> fonctionnerait aussi et sans le hachage inutile, mais un dictionnaire permet un code plus propre.

Je reçois des membres qui ont un MemberType sur Field et qui sont littéraux. Cela crée une séquence de seuls membres qui sont des valeurs enum. Ceci est robuste puisqu'un enum ne peut pas avoir d'autres champs.

public static class ControlExtensions
{
    public static void BindToEnum<TEnum>(this ComboBox comboBox)
    {
        var enumType = typeof(TEnum);

        var fields = enumType.GetMembers()
                              .OfType<FieldInfo>()
                              .Where(p => p.MemberType == MemberTypes.Field)
                              .Where(p => p.IsLiteral)
                              .ToList();

        var valuesByName = new Dictionary<string, object>();

        foreach (var field in fields)
        {
            var descriptionAttribute = field.GetCustomAttribute(typeof(DescriptionAttribute), false) as DescriptionAttribute;

            var value = (int)field.GetValue(null);
            var description = string.Empty;

            if (!string.IsNullOrEmpty(descriptionAttribute?.Description))
            {
                description = descriptionAttribute.Description;
            }
            else
            {
                description = field.Name;
            }

            valuesByName[description] = value;
        }

        comboBox.DataSource = valuesByName.ToList();
        comboBox.DisplayMember = "Key";
        comboBox.ValueMember = "Value";
    }


}
0
Jordan