wake-up-neo.com

Das ComboBox SelectionChanged-Ereignis hat einen alten Wert und keinen neuen Wert

C #, .NET 4.0, VS2010.

Neu bei WPF. Ich habe eine ComboBox in meinem MainWindow. Ich habe das SelectionChanged-Ereignis des Kombinationsfelds angehängt. Wenn ich jedoch den Wert des Kombinationsfelds im Ereignishandler untersuche, hat es den alten Wert. Dies klingt eher nach einem "SelectionChanging" -Ereignis als nach einem SelectionChanged-Ereignis. 

Wie erhalte ich den neuen Wert der ComboBox, nachdem die Auswahl tatsächlich erfolgt ist?

Zur Zeit:

this.MyComboBox.SelectionChanged += new SelectionChangedEventHandler(OnMyComboBoxChanged);

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

Beachten Sie, dass ich dasselbe Verhalten bekomme, wenn ich das Objekt verwende, das in den Ereignisargumenten übergeben wird. e.OriginalSource.

77
Matt

Laut MSDN e.AddedItems :

Ruft eine Liste mit den ausgewählten Elementen ab.

Sie könnten also Folgendes verwenden:

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

Sie können auch SelectedItem verwenden, wenn Sie string-Werte für die Items aus der sender verwenden:

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

oder

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

Da sowohl Content als auch SelectedItem Objekte sind, wäre es sicherer, .ToString() anstelle von as string zu verwenden.

94
SwDevMan81

Verwenden Sie das DropDownClosed-Ereignis anstelle von selectionChanged, wenn Sie den aktuellen Wert des Kombinationsfelds möchten.

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

Ist wirklich so einfach.

44
hidden

Der korrekte zu überprüfende Wert ist die Eigenschaft SelectedItem

Eine ComboBox ist ein zusammengesetztes Steuerelement, dessen zwei Bestandteile:

  1. The Text Part: Der Wert in diesem Teil entspricht der Text - Eigenschaft der ComboBox.
  2. The Selector Part (d. H. Der "Dropdown" -Teil): Das ausgewählte Element in diesem Teil entspricht der SelectedItem - Eigenschaft.

 Expanded ComboBox Parts

Das obige Bild wurde unmittelbar nach dem Erweitern der ComboBox aufgenommen (d. H. Vor Auswahl eines neuen Werts). An diesem Punkt sind sowohl Text als auch SelectedItem "Info", vorausgesetzt, die ComboBox-Elemente waren Strings. Wenn die ComboBox-Elemente stattdessen alle Werte eines Enums mit dem Namen "LogLevel" wären, wäre SelectedItem derzeit LogLevel.Info.

Wenn Sie auf ein Element in der Dropdown-Liste klicken, wird der Wert von SelectedItem geändert und das Ereignis SelectionChanged wird ausgelöst. Die Eigenschaft Text ist jedoch noch nicht aktualisiert, da der Text Part erst dann aktualisiert wird, nachdem der SelectionChanged -Handler abgeschlossen ist. Dies kann beobachtet werden, indem ein Haltepunkt im Handler gesetzt wird und die Steuerung betrachtet wird:

 ComboBox at breakpoint in SelectionChanged handler

Da der Text Part zu diesem Zeitpunkt noch nicht aktualisiert wurde, gibt die Text - Eigenschaft den zuvor ausgewählten Wert zurück.

44
Dave Kidder

Das hat für mich funktioniert:

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

Das hat für mich funktioniert:

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

Das folgende Ereignis wird ausgelöst, wenn der Text in der ComboBox geändert wird (wenn der ausgewählte Index geändert wird und der Text auch durch Bearbeiten geändert wird).

<ComboBox IsEditable="True" TextBoxBase.TextChanged="cbx_TextChanged" />
2
Petr Voborník

Die zweite Option hat für mich nicht funktioniert, da das .Text-Element außerhalb des Gültigkeitsbereichs war (C # 4.0 VS2008). Das war meine Lösung ...

string test = null;
foreach (ComboBoxItem item in e.AddedItems)
{
   test = item.Content.ToString();
   break;
}
1
Josh
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string newItem = ((DataRowView) e.AddedItems[0]).Row.ItemArray[0].ToString();
}
1
Buratino

Wenn Sie wirklich das SelectionChanged-Ereignis benötigen, ist die Antwort von SwDevMan81 die beste Antwort. Wenn Sie jedoch mit WPF beginnen, möchten Sie vielleicht wissen, wie Dinge auf WPF-Art und Weise erledigt werden. Dies unterscheidet sich von den alten Windows Forms-Tagen, die auf Ereignisse wie SelectionChanged, WPF und Model View ViewModel, angewiesen sind sollte Bindungen verwenden. Hier ist ein Codebeispiel:

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

}
0
Lazaro

Seltsam, dass SelectedItem die neuen Daten enthält, während SelectedValue dies nicht tut. Klingt für mich nach einem Fehler. Wenn Ihre Elemente in der Combobox andere Objekte als ComboBoxItems sind, benötigen Sie etwa Folgendes: (meine ComboBox enthält KeyValuePairs)

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 kann null sein, während Visual Studio mir ständig sagt, dass eine KeyValuePair nicht null sein kann. Deshalb verwandle ich die SelectedItem in einen nullbaren KeyValuePair<string, string>?. Dann überprüfe ich, ob selectedItem einen anderen Wert als null hat. Dieser Ansatz sollte auf den Typ des ausgewählten Artikels angewendet werden.

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

Die Verwendung von e.AddedItems[0] as kProject, wobei kProject eine Klasse ist, die die für mich bearbeiteten Daten enthält, da sie standardmäßig auf RemovedItems [0] festgelegt waren, bevor ich diese explizite Unterscheidung getroffen habe. Danke an SwDevMan81 für die ersten Informationen, die diese Frage für mich beantwortet haben.

0
kyjote

Ich musste das in VB.NET lösen. Folgendes habe ich, das scheint zu funktionieren:

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
0
zzMzz

Komplizieren Sie die Dinge nicht ohne Grund. Mit der SelectedValue-Eigenschaft können Sie einen ComboBox-Wert wie folgt einfach abrufen: YourComboBoxName.SelectedValue.ToString ().

Hinter der Szene ist die SelectedValue-Eigenschaft definiert als: SelectedValue {get; set;} Dies bedeutet, dass Sie es verwenden können, um den Wert einer ComboBox abzurufen oder festzulegen.

Die Verwendung von SelectedItem ist keine effiziente Methode zum Abrufen eines ComboBox-Werts, da dies eine Vielzahl von Auswirkungen erfordert.

0
Sam Tomashi