C #, .NET 4.0, VS2010.
Nowość w WPF. Mam ComboBox w moim MainWindow. Podłączyłem zdarzenie SelectionChanged wspomnianego pola kombi. Jeśli jednak sprawdzę wartość pola kombi w module obsługi zdarzeń, ma on starą wartość. To brzmi bardziej jak zdarzenie „SelectionChanging” niż zdarzenie SelectionChanged.
Jak uzyskać nową wartość ComboBox po dokonaniu wyboru?
W tej chwili:
this.MyComboBox.SelectionChanged += new SelectionChangedEventHandler(OnMyComboBoxChanged);
...
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
string text = this.MyComboBox.Text;
}
Uwaga: otrzymuję to samo zachowanie, jeśli używam przekazywanego obiektu w args zdarzenia, np. EOriginalSource.
SelectionChanging
w pierwszej kolejności?Odpowiedzi:
Według MSDN
e.AddedItems
:Możesz więc użyć:
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e) { string text = (e.AddedItems[0] as ComboBoxItem).Content as string; }
Możesz również użyć,
SelectedItem
jeśli używaszstring
wartości dlaItems
zsender
:private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e) { string text = (sender as ComboBox).SelectedItem as string; }
lub
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e) { string text = ((sender as ComboBox).SelectedItem as ComboBoxItem).Content as string; }
Ponieważ oba obiekty
Content
iSelectedItem
są obiektami, bezpieczniejszym podejściem byłoby użycie.ToString()
zamiastas string
źródło
ComboBox.SelectedItem
nie ma właściwość o nazwieText
, ale można to zrobićComboBox.SelectedItem as string
(chociaż to może działać tylko wtedy, gdy używaszstring
doItems
- nie testowano cokolwiek innego)Poprawną wartością do sprawdzenia w tym miejscu jest właściwość SelectedItem .
ComboBox to kontrolka złożona, której dwie części to:
Powyższe zdjęcie zostało zrobione zaraz po rozwinięciu ComboBox (tj. Przed wybraniem nowej wartości). W tym momencie zarówno Text, jak i SelectedItem to „Info”, przy założeniu, że elementy ComboBox były ciągami. Gdyby elementy ComboBox były zamiast tego wszystkimi wartościami Enum o nazwie „LogLevel”, SelectedItem byłoby obecnie LogLevel.Info .
Kliknięcie elementu w menu rozwijanym powoduje zmianę wartości SelectedItem i wywołanie zdarzenia SelectionChanged . Właściwość Text nie została jeszcze zaktualizowana, ponieważ część tekstowa nie jest aktualizowana do momentu zakończenia obsługi SelectionChanged . Można to zaobserwować, umieszczając punkt przerwania w programie obsługi i patrząc na kontrolkę:
Ponieważ część tekstowa nie została w tym momencie zaktualizowana, właściwość Text zwraca poprzednio wybraną wartość.
źródło
Użyj zdarzenia DropDownClosed zamiast selectionChanged, jeśli chcesz uzyskać bieżącą wartość pola kombi.
private void comboBox_DropDownClosed(object sender, EventArgs e) { MessageBox.Show(comboBox.Text) }
To naprawdę takie proste.
źródło
To zadziałało dla mnie:
private void AppName_SelectionChanged(object sender, SelectionChangedEventArgs e) { ComboBoxItem cbi = (ComboBoxItem)AppName.SelectedItem; string selectedText = cbi.Content.ToString(); }
źródło
To zadziałało dla mnie:
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e) { var text = ((sender as ComboBox).SelectedItem as ComboBoxItem).Content as string; }
źródło
sender
zawiera poprawną odpowiedźSelectedItem
.Następujące zdarzenie jest wyzwalane w przypadku dowolnej zmiany tekstu w ComboBox (gdy wybrany indeks zostanie zmieniony, a tekst również zostanie zmieniony przez edycję).
<ComboBox IsEditable="True" TextBoxBase.TextChanged="cbx_TextChanged" />
źródło
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e) { string newItem = ((DataRowView) e.AddedItems[0]).Row.ItemArray[0].ToString(); }
źródło
Druga opcja nie zadziałała dla mnie, ponieważ element .Text był poza zakresem (C # 4.0 VS2008). To było moje rozwiązanie ...
string test = null; foreach (ComboBoxItem item in e.AddedItems) { test = item.Content.ToString(); break; }
źródło
Musiałem rozwiązać ten problem w VB.NET. Oto, co mam, co wydaje się działać:
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
źródło
To dziwne, że SelectedItem przechowuje świeże dane, podczas gdy SelectedValue nie. Dla mnie brzmi to jak błąd. Jeśli twoje przedmioty w Combobox są obiektami innymi niż ComboBoxItems, będziesz potrzebować czegoś takiego: (moje
ComboBox
zawieraKeyValuePair
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
może być null, podczas gdy Visual Studio ciągle mówi mi, że aKeyValuePair
nie może być null. Dlatego rzuciłem wartośćSelectedItem
nullKeyValuePair<string, string>?
. Następnie sprawdzam, czyselectedItem
ma wartość inną niżnull
. To podejście powinno mieć zastosowanie do dowolnego typu wybranego przedmiotu.źródło
Jeśli naprawdę potrzebujesz
SelectionChanged
wydarzenia, najlepszą odpowiedzią jest odpowiedź SwDevMan81. Jeśli jednak zaczynasz od WPF, możesz chcieć dowiedzieć się, jak robić rzeczy w sposób WPF, który różni się od starych dni Windows Forms, które wcześniej polegały na zdarzeniach, takich jakSelectionChanged
WPF i wzorzec ViewModel widoku modelu, powinieneś użyj powiązań. Oto przykład kodu:// 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"); } } }
źródło
private void indBoxProject_SelectionChanged(object sender, SelectionChangedEventArgs e) { int NewProjID = (e.AddedItems[0] as kProject).ProjectID; this.MyProject = new kProject(NewProjID); LoadWorkPhase(); }
Użycie
e.AddedItems[0] as kProject
where kProject jest klasą, która przechowuje dane, działało dla mnie, ponieważ domyślnie korzystało z RemovedItems [0], zanim dokonałem tego wyraźnego rozróżnienia. Dzięki SwDevMan81 za wstępne informacje, które odpowiedziały mi na to pytanie.źródło
Nie komplikuj rzeczy bez powodu. Używając właściwości SelectedValue, możesz łatwo pobrać wybraną wartość ComboBox, taką jak ta: YourComboBoxName.SelectedValue.ToString ().
Za sceną właściwość SelectedValue jest zdefiniowana jako: SelectedValue {get; set;} oznacza to, że możesz go użyć do pobrania lub ustawienia wartości ComboBox.
Używanie SelectedItem nie jest wydajnym sposobem na uzyskanie wartości ComboBox, ponieważ wymaga wielu konsekwencji.
źródło
Możesz sprawdzić SelectedIndex lub SelectedValue lub SelectedItem właściwość w zdarzeniu SelectionChanged kontrolki Combobox.
źródło
To powinno działać dla Ciebie ...
int myInt= ((data)(((object[])(e.AddedItems))[0])).kid;
źródło
Rozwiązałem to za pomocą zdarzenia DropDownClosed, ponieważ jest ono uruchamiane nieco po zmianie wartości.
źródło