C #, .NET 4.0, VS2010.
Nouveau sur WPF. J'ai une ComboBox sur ma MainWindow. J'ai accroché l'événement SelectionChanged de la liste déroulante. Cependant, si j'examine la valeur de la liste déroulante dans le gestionnaire d'événements, celle-ci 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 une fois la sélection effectuée?
Actuellement:
this.MyComboBox.SelectionChanged += new SelectionChangedEventHandler(OnMyComboBoxChanged);
...
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
string text = this.MyComboBox.Text;
}
Notez que j'obtiens le même comportement si j'utilise l'objet passé dans les arguments d'événement, par exemple. e.OriginalSource.
Selon MSDN, e.AddedItems
:
Obtient une liste contenant les éléments sélectionnés.
Pour que vous puissiez 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 Items
à partir de sender
:
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
string text = (sender as ComboBox).SelectedItem as string;
}
ou
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
string text = ((sender as ComboBox).SelectedItem as ComboBoxItem).Content as string;
}
Content
et SelectedItem
étant des objets, une approche plus sûre consisterait à utiliser .ToString()
au lieu de as string
Utilisez l'événement DropDownClosed au lieu de selectionChanged si vous voulez la valeur actuelle de la liste déroulante.
private void comboBox_DropDownClosed(object sender, EventArgs e)
{
MessageBox.Show(comboBox.Text)
}
Est-ce vraiment si simple?.
La valeur correcte à vérifier ici est la propriété SelectedItem.
Une ComboBox est un contrôle composite composé de deux parties:
L’image ci-dessus a été prise immédiatement après l’extension de la ComboBox (c’est-à-dire avant la sélection d’une nouvelle valeur). À ce stade, Text _ et SelectedItem_ sont «Info», en supposant que les éléments ComboBox étaient des chaînes. Si les éléments ComboBox étaient à la place toutes les valeurs d'un Enum appelé "LogLevel", SelectedItem serait actuellement LogLevel.Info.
Lorsque l'utilisateur clique sur un élément du menu déroulant, la valeur de SelectedItem est modifiée et l'événement SelectionChanged est déclenché. La propriété Texte n'est pas encore mise à jour, car la Partie de texte n'est mise à jour qu'après la fin du gestionnaire SelectionChanged. Ceci peut être observé en mettant un point d'arrêt dans le gestionnaire et en regardant le contrôle:
La partie de texte n'ayant pas encore été mise à jour, la propriété texte renvoie la valeur précédemment sélectionnée.
Cela a fonctionné pour moi:
private void AppName_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBoxItem cbi = (ComboBoxItem)AppName.SelectedItem;
string selectedText = cbi.Content.ToString();
}
Cela a fonctionné pour moi:
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
var text = ((sender as ComboBox).SelectedItem as ComboBoxItem).Content as string;
}
L'événement suivant est déclenché pour toute modification du texte dans la zone de liste déroulante (lorsque l'index sélectionné est modifié et lorsque le texte est également modifié).
<ComboBox IsEditable="True" TextBoxBase.TextChanged="cbx_TextChanged" />
La deuxième option ne fonctionnait pas pour moi car 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;
}
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
string newItem = ((DataRowView) e.AddedItems[0]).Row.ItemArray[0].ToString();
}
Si vous avez vraiment besoin de l'événement SelectionChanged
, la meilleure réponse est la réponse de SwDevMan81. Toutefois, si vous débutez avec WPF, vous voudrez peut-être apprendre à faire les choses de la même manière que WPF, qui diffère des anciens jours Windows Forms qui reposaient sur des événements tels que SelectionChanged
, avec WPF et le modèle View View Model View. devrait utiliser des liaisons. Voici un exemple de code:
// In the Views folder: /Views/MyWindow.xaml:
// ...
<ComboBox ItemsSource="{Binding MyViewModel.MyProperties, RelativeSource={RelativeSource AncestorType=Window}}"
SelectedItem="{Binding MyViewModel.MyProperty , RelativeSource={RelativeSource AncestorType=Window}}" />
// ...
// In the Views folder: /Views/MyWindow.xaml.cs:
public partial class MyWindow : Window
{
public MyViewModelClass MyViewModel {
get { return _viewModel; }
private set { _viewModel = value;}
}
public MyWindow()
{
MyViewModel.PropertyChanged += MyViewModel_PropertyChanged;
}
void MyViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "MyProperty")
{
// Do Work
// Put your logic here!
}
}
}
using System.ComponentModel;
// In your ViewModel folder: /ViewModels/MyViewModelClass.cs:
public class MyViewModelClass : INotifyPropertyChanged
{
// INotifyPropertyChanged implementation:
private void NotifyPropertyChanged(string propertyName = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }
public event PropertyChangedEventHandler PropertyChanged;
// Selected option:
private string _myProperty;
public string MyProperty {
get { return _myProperty; }
set { _myProperty = value; NotifyPropertyChanged("MyProperty"); }
}
// Available options:
private List<string> _myProperties;
public List<string> MyProperties {
get { return _myProperties; }
set { _myProperties = value; NotifyPropertyChanged("MyProperties"); }
}
}
Il est étrange que SelectedItem contienne les données fraîches, alors que SelectedValue ne le fait pas. Cela ressemble à un bug pour moi. Si vos éléments de la liste déroulante sont des objets autres que ComboBoxItems, vous aurez besoin de quelque chose comme ceci: (ma ComboBox
contient KeyValuePair
s)
var selectedItem = (KeyValuePair<string, string>?)(sender as ComboBox).SelectedItem;
if (!selectedItem.HasValue)
return;
string selectedValue = selectedItem.Value.Value; // first .Value gets ref to KVPair
ComboBox.SelectedItem
peut être null, alors que Visual Studio n'arrête pas de me dire qu'une KeyValuePair
ne peut pas être nulle. C'est pourquoi j'ai converti la SelectedItem
en un KeyValuePair<string, string>?
nullable. Ensuite, je vérifie si selectedItem
a une valeur autre que null
. Cette approche devrait être applicable à tout type d’élément choisi.
private void indBoxProject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
int NewProjID = (e.AddedItems[0] as kProject).ProjectID;
this.MyProject = new kProject(NewProjID);
LoadWorkPhase();
}
L'utilisation de e.AddedItems[0] as kProject
, où kProject est une classe qui contient les données, a fonctionné pour moi car elle correspondait par défaut à RemovedItems [0] avant que je fasse cette distinction explicite. Merci SwDevMan81 pour les informations initiales qui ont répondu à cette question pour moi.
J'avais besoin de résoudre cela en VB.NET. Voici ce que j'ai 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
Ne compliquez pas les choses sans raison. En utilisant la propriété SelectedValue, vous pouvez facilement obtenir une valeur ComboBox sélectionnée, telle que: YourComboBoxName.SelectedValue.ToString ().
Derrière la scène, la propriété SelectedValue est définie comme suit: SelectedValue {get; set;} cela signifie que vous pouvez l'utiliser pour obtenir ou définir la valeur d'un ComboBox.
Utiliser SelectedItem n'est pas un moyen efficace d'obtenir une valeur ComboBox car cela nécessite beaucoup de ramifications.