ComboBox- SelectionChanged event has old value, not new value

C#WpfCombobox.Net 4.0Selectionchanged

C# Problem Overview


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.

C# Solutions


Solution 1 - C#

According to MSDN, e.AddedItems:

> Gets a list that contains the items that were selected.

So you could use:

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

You could also use SelectedItem if you use string values for the Items from the sender:

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

or

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

Since both Content and SelectedItem are objects, a safer approach would be to use .ToString() instead of as string

Solution 2 - C#

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.

Solution 3 - C#

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.

Solution 4 - C#

This worked for me:

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

Solution 5 - C#

This worked for me:

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

Solution 6 - C#

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

Solution 7 - C#

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

Solution 8 - C#

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

Solution 9 - C#

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

Solution 10 - C#

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

Solution 11 - C#

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.

Solution 12 - C#

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.

Solution 13 - C#

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.

Solution 14 - C#

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

Solution 15 - C#

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

Solution 16 - C#

This should work for you ...

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

Solution 17 - C#

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMattView Question on Stackoverflow
Solution 1 - C#SwDevMan81View Answer on Stackoverflow
Solution 2 - C#Dave KidderView Answer on Stackoverflow
Solution 3 - C#hiddenView Answer on Stackoverflow
Solution 4 - C#Ramon View Answer on Stackoverflow
Solution 5 - C#Бранко ПејићView Answer on Stackoverflow
Solution 6 - C#Petr VoborníkView Answer on Stackoverflow
Solution 7 - C#JoshView Answer on Stackoverflow
Solution 8 - C#BuratinoView Answer on Stackoverflow
Solution 9 - C#LazaroView Answer on Stackoverflow
Solution 10 - C#zzMzzView Answer on Stackoverflow
Solution 11 - C#sorrymissjacksonView Answer on Stackoverflow
Solution 12 - C#kyjoteView Answer on Stackoverflow
Solution 13 - C#Sam TomashiView Answer on Stackoverflow
Solution 14 - C#Hieu - 7347514View Answer on Stackoverflow
Solution 15 - C#Ali SafariView Answer on Stackoverflow
Solution 16 - C#soulexitView Answer on Stackoverflow
Solution 17 - C#user5028920View Answer on Stackoverflow