Update
After a bit of investigating. What seems to be the issue is that the SelectedValue/SelectedItem is occurring before the Item source is finished loading. If I sit in a break point and wait a few seconds it works as expected. Don't know how I'm going to get around this one.
End Update
I have an application using in WPF using MVVM with a ComboBox. Below is the ViewModel Example. The issue I'm having is when we leave our page and migrate back the ComboBox is not selecting the current Value that is selected.
View Model
public class MyViewModel
{
private MyObject _selectedObject;
private Collection<Object2> _objects;
private IModel _model;
public MyViewModel(IModel model)
{
_model = model;
_objects = _model.GetObjects();
}
public Collection<MyObject> Objects
{
get
{
return _objects;
}
private set
{
_objects = value;
}
}
public MyObject SelectedObject
{
get
{
return _selectedObject;
}
set
{
_selectedObject = value;
}
}
}
For the sake of this example lets say MyObject has two properties (Text and Id). My XAML for the ComboBox looks like this.
XAML
<ComboBox Name="MyComboBox" Height="23" Width="auto"
SelectedItem="{Binding Path=SelectedObject,Mode=TwoWay}"
ItemsSource="{Binding Objects}"
DisplayMemberPath="Text"
SelectedValuePath="Id">
No matter which way I configure this when I come back to the page and the object is reassembled the ComboBox will not select the value. The object is returning the correct object via the get in the property though.
I'm not sure if this is just an issue with the way the ComboBox and MVVM pattern works. The text box binding we are doing works correctly.
I had the same problem. The thing is. The selected item doesnt know which object it should use from the collection. So you have to say to the selected item to use the item from the collection.
I hope this helps.
When leaving the current page, the
CollectionView
associated with theItemsSource
property of theComboBox
is purged. And because theComboBox
IsSyncronizedWithCurrent
property is true by default, theSelectedItem
andSelectedValue
properties are reset.This seems to be an internal data type issue in the binding. As others suggested above, if you use
SelectedValue
instead by binding to an int property on the viewmodel, it will work. A shortcut for you would be to override theEquals
operator on MyObject so that when comparing two MyObjects, the actualId
properties are compared.Another hint: If you do restructure your viewmodels and use
SelectedValue
, use it only whenSelectedValuePath=Id
whereId
isint
. If using a string key, bind to theText
property of theComboBox
instead ofSelectedValue
.I have a very simply answer for this problem. First add the following code to the View IsSynchronizedWithCurrentItem="True".
Next when ever you assign a new object in the ViewModel to that Property SelectedObject should be saved to that Property and not the private member.
The viewmodel Proptery should look like this
This should fix the issue.
Have you tried implementing
INotifyPropertyChanged
in your viewmodel, and then raise thePropertyChanged
event when theSelectedItem
gets set?If this in itself doesn't fix it, then you will be able to manually raise the
PropertyChanged
event yourself when navigating back to the page, and that should be enough to get WPF to redraw itself and show the correct selected item.I have had similar issues and it was solved by making sure I was implementing IEquatable properly. When the binding occurs, it is trying to see if the objects match so make sure you are properly implementing your equality checking.
I solved the problem by adding dispatcher in UserControl_Loaded event