102 votes

ComboBox- L'événement SelectionChanged a l'ancienne valeur et non la nouvelle.

C#, .NET 4.0, VS2010.

Nouveau dans WPF. J'ai une ComboBox sur ma MainWindow. J'ai accroché l'événement SelectionChanged de ladite boîte combo. Cependant, si j'examine la valeur de la boîte combo dans le gestionnaire d'événement, elle a l'ancienne valeur. Cela ressemble plus à un événement "SelectionChanging" qu'à un événement SelectionChanged.

Comment puis-je obtenir la nouvelle valeur de la ComboBox après que la sélection ait eu lieu ?

Actuellement :

this.MyComboBox.SelectionChanged += new SelectionChangedEventHandler(OnMyComboBoxChanged);

...
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string text = this.MyComboBox.Text;
}

Remarque : j'obtiens le même comportement si j'utilise l'objet transmis dans les arguments de l'événement, par exemple e.OriginalSource.

2 votes

Je viens de tomber sur le même problème - merci ! Est-ce que c'est en fait un bug, et il aurait dû être nommé SelectionChanging en premier lieu ?

0 votes

L'inspection du code source de la méthode ComboBox.OnSelectionChanged montre que celle-ci publie l'événement et puis traite l'élément sélectionné. Dans un problème connexe J'ai utilisé la réflexion pour le forcer à traiter l'élément sélectionné à partir de mon gestionnaire d'événement SelectionChanged.

115voto

SwDevMan81 Points 22634

Selon MSDN, e.AddedItems :

Obtient une liste qui contient les éléments qui ont été sélectionnés.

Donc vous pourriez utiliser :

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string text = (e.AddedItems[0] as ComboBoxItem).Content as string;
}

Vous pouvez également utiliser SelectedItem si vous utilisez string pour les Items de la sender :

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string text = (sender as ComboBox).SelectedItem as string;
}

o

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string text = ((sender as ComboBox).SelectedItem as ComboBoxItem).Content as string;
}

Puisque les deux Content y SelectedItem sont des objets, une approche plus sûre serait d'utiliser .ToString() au lieu de as string

11 votes

Intéressant ... il a la nouvelle valeur. Et RemovedItems a l'ancienne. Le nom de cet événement est un peu mal choisi, du moins à mon avis. Quand je vois SelectionChanged, je m'attends à ce que l'état de l'objet ait changé. Je peux voir comment cela nous donne un peu plus d'informations cependant.

1 votes

Oui, je pense que c'est parce que le changement a eu lieu, mais n'a pas été validé ? C'est juste une supposition. Vous pourriez être en mesure d'obtenir le texte de l'élément sélectionné, voir mon édition.

3 votes

ComboBox.SelectedItem n'a pas de propriété appelée Text mais vous pouvez faire ComboBox.SelectedItem as string (bien que cela ne fonctionne que si vous utilisez string para el Items - pas testé autre chose)

52voto

jvelez Points 641

Utilisez l'événement DropDownClosed au lieu de selectionChanged si vous souhaitez obtenir la valeur actuelle de la liste déroulante.

private void comboBox_DropDownClosed(object sender, EventArgs e)
{
   MessageBox.Show(comboBox.Text) 
}

C'est vraiment aussi simple que ça.

10 votes

@jvelez Je pense que ça ne se déclenche pas quand on utilise un clavier.

0 votes

Ça craint. NoviceProgrammeur qui savait... !

0 votes

Ça a marché pour moi. Il est comique qu'il ne soit pas possible d'obtenir facilement la valeur sélectionnée lorsque la sélection a changé. Je suis sûr qu'il y a une bonne raison pour cela, mais bon sang.

10voto

Ramon Points 71

Cela a marché pour moi :

private void AppName_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
   ComboBoxItem cbi = (ComboBoxItem)AppName.SelectedItem;
   string selectedText = cbi.Content.ToString();
}

0 votes

D'une manière ou d'une autre, seul SelectedItem est alimenté avec le nouvel élément, et non SelectedValue.

1voto

Josh Points 11

La deuxième option n'a pas fonctionné pour moi parce que l'élément .Text était hors de portée (C# 4.0 VS2008). C'était ma solution...

string test = null;
foreach (ComboBoxItem item in e.AddedItems)
{
   test = item.Content.ToString();
   break;
}

0voto

MikeG Points 113

Je devais résoudre ce problème en VB.NET. Voici ce que j'ai obtenu et qui semble fonctionner :

Private Sub ComboBox1_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles ComboBox_AllSites.SelectionChanged
   Dim cr As System.Windows.Controls.ComboBoxItem = ComboBox1.SelectedValue
   Dim currentText = cr.Content
   MessageBox.Show(currentText)
End Sub

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