c# wpf - El evento ComboBox-SelectionChanged tiene un valor anterior, no un valor nuevo




drop down (13)

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.


Answers

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í.


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" />

Esto debería funcionar para ti ...

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

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

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


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.


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

}

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


Esto funcionó para mí:

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

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


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.


Esto funcionó para mí:

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

Intenta usar algo como

File.Create

Crea o sobrescribe un archivo en la ruta especificada.





c# wpf combobox .net-4.0 selectionchanged