2009-12-05 3 views
2

J'ai un comboBox simple avec quelques éléments de valeur/texte dedans. J'ai utilisé ComboBox.DisplayMember et ComboBox.ValueMember pour définir correctement la valeur/texte. Lorsque j'essaie d'obtenir la valeur, elle renvoie une chaîne vide. Voici mon code:Impossible d'obtenir la valeur de ComboBox

événement FormLoad:

cbPlayer1.ValueMember = "Value"; 
cbPlayer1.DisplayMember = "Text"; 

SelectIndexChanged d'événement ComboBox:

cbPlayer1.Items.Add(new { Value = "3", Text = "This should have a value of 3" }); 
MessageBox.Show(cbPlayer1.SelectedValue+""); 

Et il retourne une boîte de dialogue vide. J'ai aussi essayé ComboBox.SelectedItem.Value (VS qui voit, voir photo), mais il ne compile pas:

'object' does not contain a definition for 'Value' and no extension method 'Value' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?) 

alt text

Qu'est-ce que je fais mal?

Répondre

6

Vous ne savez pas ce que ComboBox.SelectedValue signifie, il a une propriété SelectedItem. Cela ne serait pas défini lorsque vous ajoutez un élément, uniquement lorsque l'utilisateur fait une sélection.

La propriété Items est une collection de System.Object. Cela permet à une zone de liste déroulante pour stocker et afficher n'importe quel type d'objet de classe. Mais vous devrez le passer de l'objet à votre type de classe pour utiliser l'objet sélectionné dans votre code. Cela ne peut pas fonctionner dans votre cas, vous avez ajouté un objet de type anonyme. Vous devez déclarer une petite classe d'assistance pour stocker les propriétés Value et Text.Un exemple de code:

public partial class Form1 : Form { 
    public Form1() { 
     InitializeComponent(); 
     comboBox1.Items.Add(new Item(1, "one")); 
     comboBox1.Items.Add(new Item(2, "two")); 
     comboBox1.SelectedIndexChanged += new EventHandler(comboBox1_SelectedIndexChanged); 
    } 
    void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { 
     Item item = comboBox1.Items[comboBox1.SelectedIndex] as Item; 
     MessageBox.Show(item.Value.ToString()); 
    } 
    private class Item { 
     public Item(int value, string text) { Value = value; Text = text; } 
     public int Value { get; set; } 
     public string Text { get; set; } 
     public override string ToString() { return Text; } 
    } 
    } 
+0

C'est la méthode que je préfère. Merci pour l'aide, ça a marché. – ademers

2

Comme vous l'avez vu dans le débogueur, SelectedItem contient les informations dont vous avez besoin. Mais pour accéder à SelectedItem.Value, vous devez convertir SelectedItem au type approprié (ce qui est problématique si vous utilisez un type anonyme) ou utiliser la réflexion. (VS ne peut pas compiler SelectedItem.Value car à la compilation temps VS ne sait que SelectedItem est de type objet, qui ne possède pas une propriété de valeur.)

Pour utiliser la réflexion pour obtenir le membre de la valeur, l'utilisation de type .InvokeMember avec BindingFlags.GetProperty. Pour fusionner SelectedItem, déclarez un type nommé avec les propriétés Value et Text au lieu d'utiliser un type anonyme et ajoutez des occurrences du type nommé à ComboBox, au lieu des instances du type anonyme. Puis cast SelectedItem: ((MyType) (cb.SelectedItem)). Valeur.

1

Je ne sais pas pourquoi SelectedValue ne renvoie rien ... Je suppose que cela peut être dû au fait que vous n'utilisez pas la liaison de données (DataSource). Vous devriez essayer d'assigner une liste de cartes à la propriété DataSource.

En ce qui concerne le problème avec SelectedItem: ComboBox.SelectedItem est de type Object, qui n'a pas de propriété nommée Value. Vous devez le convertir en type d'élément. mais comme il est un type anonyme, vous ne pouvez pas ... vous devriez probablement créer un type pour maintenir la valeur et le texte de la carte, et coulé à ce type:

Card card = ComboBox.SelectedItem as Card; 
if (card != null) 
{ 
    // do something with card.Value 
} 
1

Vous modifiez le contenu de ComboBox dans le gestionnaire SelectedIndexChanged. Lorsque vous modifiez le contenu, les éléments sélectionnés sont désactivés. Définissez que vous lisez null, qui est affiché dans la boîte de message en tant que chaîne vide.

0

Je suis curieux de savoir si vous liez la liste déroulante à une collection ou si vous la remplissez manuellement. Si vous liez la zone de liste déroulante à une source de données quelconque ... vous devez ajouter des éléments à la source de données, pas à la zone de liste déroulante elle-même. Lorsqu'un élément est ajouté à la source de données, la liste déroulante doit être mise à jour en nature.

Si vous n'êtes pas lié, l'ajout d'un élément ne provoquera pas la sélection de cet élément. Vous devrez soit attendre que l'utilisateur sélectionne l'élément, soit sélectionner par programme l'élément dans le code.

0

Pour éviter d'avoir à créer une nouvelle classe pour tous vos comboboxes je vous suggère simplement d'utiliser un KeyValuePair comme dans l'exemple suivant:

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

cbPlayer1.DataSource = new List<KeyValuePair<string,string>>() 
{new KeyValuePair<string,string>("3","This should have the value of 3")}; 

Vous avez encore besoin de jeter la valeur sélectionnée

string selectedValue = (string)cbPlayer1.SelectedValue; 

MessageBox.Show(selectedValue); 
Questions connexes