[c#] ComboBox- SelectionChanged event has old value, not new value

C#, .NET 4.0, VS2010.

New to WPF. I have a ComboBox on my MainWindow. I hooked the SelectionChanged event of said combo box. However, if I examine the value of the combo box in the event handler, it has the old value. This sounds more like a "SelectionChanging" event, than a SelectionChanged event.

How do I get the new value of the ComboBox after the selection has actually happend?

Currently:

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

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

Note, I get the same behaviour if I use the object being passed in the event args, e.g. e.OriginalSource.

This question is related to c# wpf combobox .net-4.0 selectionchanged

The answer is


This worked for me:

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

I solved this by using the DropDownClosed event because this fires slightly after the value is changed.


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

Following event is fired for any change of the text in the ComboBox (when the selected index is changed and when the text is changed by editing too).

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

This should work for you ...

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

Don't complicate things for no reason. Using SelectedValue property you can easily get a selected ComboBox value like this: YourComboBoxName.SelectedValue.ToString().

Behind the scene the SelectedValue property is defined as: SelectedValue{get; set;} this means you can use it to get or set the value of a ComboBox.

Using SelectedItem is not an efficient way to get a ComboBox value since it requires a lot of ramifications.


The correct value to check here is the SelectedItem property.

A ComboBox is a composite control with two of its parts being:

  1. The Text Part: the value in the this part corresponds to the Text property of the ComboBox.
  2. The Selector Part (i.e. the "drop-down" part): The selected item in this part corresponds to the SelectedItem property.

Expanded ComboBox Parts

The image above was taken immediately after the ComboBox was expanded (i.e. before selecting a new value). At this point both Text and SelectedItem are "Info", assuming the ComboBox items were strings. If the ComboBox items were instead all the values of an Enum called "LogLevel", SelectedItem would currently be LogLevel.Info.

When an item in the drop-down is clicked on, the value of SelectedItem is changed and the SelectionChanged event is raised. The Text property isn't updated yet, though, as the Text Part isn't updated until after the SelectionChanged handler is finished. This can be observed by putting a breakpoint in the handler and looking at the control:

ComboBox at breakpoint in SelectionChanged handler

Since the Text Part hasn't been updated at this point, the Text property returns the previously selected value.


The second option didn't work for me because the .Text element was out of scope (C# 4.0 VS2008). This was my solution...

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

You can check SelectedIndex or SelectedValue or SelectedItem property in the SelectionChanged event of the Combobox control.


If you really need the SelectionChanged event, then the best answer is SwDevMan81's answer. However, if you are starting with WPF, then you might want to learn how to do things the WPF way, which is different than the old Windows Forms days that used to rely on events like SelectionChanged, with WPF and Model View ViewModel pattern, you should use bindings. Here is a code example:

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

}

Use the DropDownClosed event instead of selectionChanged if you want the current value of the combo box.

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

Is really that simple.


This worked for me:

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

From SelectionChanged event of a combobox you can get the selected item text as follow:

        private void myComboBox_SelectionChanged (object sender, SelectionChangedEventArgs e)
        {
        ComboBoxItem comboBoxItem = (ComboBoxItem) e.AddedItems[0];
        string selectedItemText = comboBoxItem.Content.ToString();
        }

I needed to solve this in VB.NET. Here's what I've got that seems to work:

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

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

The use of the e.AddedItems[0] as kProject where kProject is a class that holds the data worked for me as it was defaulting to the RemovedItems[0] before I have made this explicit distinction. Thanks SwDevMan81 for the initial information that answered this question for me.


It's weird that SelectedItem holds the fresh data, whereas SelectedValue doesn't. Sounds like a bug to me. If your items in the Combobox are objects other than ComboBoxItems, you will need something like this: (my ComboBox contains 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 can be null, whereas Visual Studio keeps telling me that a KeyValuePair can't be null. That's why I cast the SelectedItem to a nullable KeyValuePair<string, string>?. Then I check if selectedItem has a value other than null. This approach should be applicable to whatever type your selected item actually is.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to wpf

Error: the entity type requires a primary key Reportviewer tool missing in visual studio 2017 RC Pass command parameter to method in ViewModel in WPF? Calling async method on button click Setting DataContext in XAML in WPF How to resolve this System.IO.FileNotFoundException System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll? Binding an Image in WPF MVVM How to bind DataTable to Datagrid Setting cursor at the end of any text of a textbox

Examples related to combobox

How to set combobox default value? PHP code to get selected text of a combo box How to add items to a combobox in a form in excel VBA? How add items(Text & Value) to ComboBox & read them in SelectedIndexChanged (SelectedValue = null) Get Selected value of a Combobox jQuery "on create" event for dynamically-created elements How to get the selected item of a combo box to a string variable in c# HTML combo box with option to type an entry twitter bootstrap autocomplete dropdown / combobox with Knockoutjs C# winforms combobox dynamic autocomplete

Examples related to .net-4.0

TLS 1.2 in .NET Framework 4.0 Is it possible to run a .NET 4.5 app on XP? What and When to use Tuple? Fixing slow initial load for IIS Exception: "URI formats are not supported" What is the best way to implement a "timer"? Twitter Bootstrap and ASP.NET GridView How can I convert this foreach code to Parallel.ForEach? "This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded" Differences between .NET 4.0 and .NET 4.5 in High level in .NET

Examples related to selectionchanged

ComboBox- SelectionChanged event has old value, not new value