c# - drop down list wpf




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

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

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

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

}

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