web-dev-qa-db-fra.com

ComboBox C # avec texte et valeur

Duplicata possible:
Combobox C # Winforms avec étiquette et valeur

Comment aborder le stockage d'une valeur d'affichage et d'une valeur réelle dans un ComboBox?

C'est-à-dire que la ComboBox affiche:

  • Détruire le monde
  • Fronde de feu
  • Invocation de Cthulhu

mais les valeurs récupérées sont:

  • dw
  • ss
  • sc

Je veux pouvoir récupérer la valeur de l'élément sélectionné d'une manière similaire à ceci:

string selectedValue = combobox1.SelectedValue

Code mis à jour en réponse aux réponses:

Dictionary<string, string> filterItems = new Dictionary<string, string>
{
    {"Destroy World", "dw"},
    {"Fire Slingshot", "fs"},
    {"Summon Cthulu", "sc"},
};
this.options_filterby.DataSource = new BindingSource(filterItems, null);
this.options_filterby.DisplayMember = "Key";
this.options_filterby.ValueMember = "Value";

Maintenant, pour une raison quelconque, bien que les DisplayMembers soient absolument corrects, les ValueMembers renvoient des objets de dictionnaire. Encore plus étrange, après un certain temps, les ValueMembers renverront éventuellement des chaînes comme prévu.

private void options_filterby_SelectedIndexChanged(object sender, EventArgs e)
{
    MessageBox.Show(options_filterby.SelectedValue.ToString());
}

Cela retourne les dictionnaires pour les premières fois que je change l'élément sélectionné de la zone de liste déroulante, mais retourne finalement les chaînes selon les besoins.

Mise à jour: corrigée (impossible d'ajouter en tant que solution car la question a été fermée)

En réponse au problème ci-dessus, le correctif consiste à définir les propriétés DisplayMember et ValueMember avant DataSource. Je suppose que c'est un bug. Le code doit se lire:

this.options_filterby.DisplayMember = "Key";
this.options_filterby.ValueMember = "Value";
this.options_filterby.DataSource = new BindingSource(filterItems, null);
20
CJxD

La collection ComboBox.Items stocke des valeurs de type object. Il peut donc stocker tout type de type que vous désirez. Il génère la valeur display à partir de la méthode ToString () de l'objet. Pour obtenir la valeur real, transtypez simplement l'objet au type de votre classe.

10
Hans Passant

Vous utilisez DisplayMember et ValueMember pour déterminer ce que la zone de liste déroulante affichera et ce qui sera renvoyé par SelectedValue. Lorsque vous définissez la propriété DataSource, le ComboBox utilisera la propriété décrite par DisplayMember pour rendre une chaîne à l'utilisateur.


Quelque chose comme ça

public class Item {
  string Name { get; set; }
  string Value { get; set; }
}

ComboBox box = new ComboBox();
box.DisplayMember = "Name";
box.ValueMember = "Value";
box.DataSource = new [] { new Item() { "Test", "test" } };

Si vous ne définissez pas ValueMember, l'élément réel est renvoyé à la place, et si vous ne définissez pas DisplayMember, la méthode items ToString() sera utilisée pour obtenir la chaîne présenté à l'utilisateur.


Je ne sais pas si cela fonctionnera ou si cela peut changer ce que vous avez, mais vous pouvez au moins l'essayer :) Le fait est que je ne suis pas certain de ce que fait BindingSource lorsqu'il obtient un dictionnaire comme source de données. Je suppose que cela le traite comme un IEnumerable<KeyValuePair<>>, Donc votre code devrait fonctionner, mais bon, ce n'est pas le cas, alors peut-être que cela ..

BindingSource source = new BindingSource();
source.DataSource = typeof(KeyValuePair<string, string>);
foreach (KeyValuePair<string, string> pair in filterItems) {
    source.Add(pair);
}
options_filterby = source;
8
Patrick