drop down c# wpf combobox .net-4.0 selectionchanged

c# - down - combobox wpf



El evento ComboBox- SelectionChanged tiene un valor anterior, no un valor nuevo (14)

De acuerdo con MSDN, e.AddedItems :

Obtiene una lista que contiene los elementos que se seleccionaron.

Entonces podrías usar:

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

También puede usar SelectedItem si usa valores de string para los Items del 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; }

Dado que tanto Content como SelectedItem son objetos, un enfoque más seguro sería utilizar .ToString() lugar de hacerlo as string

C #, .NET 4.0, VS2010.

Nuevo en WPF. Tengo un ComboBox en mi MainWindow. Enganché el evento SelectionChanged de dicho cuadro combinado. Sin embargo, si examino el valor del cuadro combinado en el controlador de eventos, tiene el valor anterior. Esto suena más como un evento "SelectionChanging" que como un evento SelectionChanged.

¿Cómo obtengo el nuevo valor de ComboBox después de que la selección haya sucedido realmente?

Actualmente:

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

Tenga en cuenta que obtengo el mismo comportamiento si uso el objeto que se pasa en los eventos args, egeOriginalSource.


El siguiente evento se activa para cualquier cambio del texto en el ComboBox (cuando se cambia el índice seleccionado y cuando el texto se modifica editando también).

<ComboBox IsEditable="True" TextBoxBase.TextChanged="cbx_TextChanged" />


El valor correcto para comprobar aquí es la propiedad SelectedItem .

Un ComboBox es un control compuesto con dos de sus partes que son:

  1. La parte de texto : el valor en esta parte corresponde a la propiedad de texto de ComboBox.
  2. La parte del selector (es decir, la parte "desplegable"): el elemento seleccionado en esta parte corresponde a la propiedad SelectedItem .

La imagen de arriba fue tomada inmediatamente después de que el ComboBox se expandió (es decir, antes de seleccionar un nuevo valor). En este punto, tanto Text como SelectedItem son "Información", suponiendo que los elementos de ComboBox fueran cadenas. Si los elementos de ComboBox fueran todos los valores de un Enum llamado "LogLevel", SelectedItem sería actualmente LogLevel.Info .

Cuando se hace clic en un elemento del menú desplegable, el valor de SelectedItem cambia y se genera el evento SelectionChanged . Sin embargo, la propiedad Text no se ha actualizado aún, ya que la parte de texto no se actualiza hasta que finaliza el manejador SelectionChanged . Esto se puede observar poniendo un punto de interrupción en el controlador y mirando el control:

Como la parte de texto no se ha actualizado en este punto, la propiedad de texto devuelve el valor seleccionado previamente.


Es extraño que SelectedItem contenga los datos nuevos, mientras que SelectedValue no. Me parece un error. Si sus elementos en el Combobox son objetos distintos de ComboBoxItems, necesitará algo como esto: (mi ComboBox contiene 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 puede ser nulo, mientras que Visual Studio sigue diciéndome que un KeyValuePair no puede ser nulo. Es por eso que KeyValuePair<string, string>? el SelectedItem a un KeyValuePair<string, string>? . Luego verifico si selectedItem tiene un valor distinto de null . Este enfoque debería ser aplicable al tipo de elemento seleccionado.


Esto debería funcionar para ti ...

int myInt= ((data)(((object[])(e.AddedItems))[0])).kid;


Esto funcionó para mí:

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


Esto funcionó para mí:

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


La segunda opción no funcionó porque el elemento .Text estaba fuera del alcance (C # 4.0 VS2008). Esta fue mi solución ...

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


Lo resolví utilizando el evento DropDownClosed porque esto se dispara un poco después de que se cambia el valor.


Necesitaba resolver esto en VB.NET. Esto es lo que tengo que parece funcionar:

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


Si realmente necesita el evento SelectionChanged , la mejor respuesta es la respuesta de SwDevMan81. Sin embargo, si está comenzando con WPF, entonces puede querer aprender cómo hacer las cosas de la manera WPF, que es diferente de los días anteriores de Windows Forms que solían basarse en eventos como SelectionChanged , con WPF y el modelo Model View View Model, usted debería usar enlaces. Aquí hay un ejemplo de código:

// 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"); } } }


Utilice el evento DropDownClosed en lugar de selectionChanged si desea el valor actual del cuadro combinado.

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

Es realmente así de simple


private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e) { string newItem = ((DataRowView) e.AddedItems[0]).Row.ItemArray[0].ToString(); }


private void indBoxProject_SelectionChanged(object sender, SelectionChangedEventArgs e) { int NewProjID = (e.AddedItems[0] as kProject).ProjectID; this.MyProject = new kProject(NewProjID); LoadWorkPhase(); }

El uso de e.AddedItems[0] as kProject donde kProject es una clase que mantiene los datos trabajados para mí como estaba por defecto en RemovedItems [0] antes de hacer esta distinción explícita. Gracias SwDevMan81 por la información inicial que respondió esta pregunta por mí.