Update
After a bit of investigating. What seems to be the issue is that the SelectedValue/SelectedItem is occurring before the Item source is finis
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.
public MyObject SelectedObject
{
get
{
Objects.find(x => x.id == _selectedObject.id)
return _selectedObject;
}
set
{
_selectedObject = value;
}
}
I hope this helps.
You can also bind your SelectedIndex to a property in your ViewModel and manipulate your SelectedItem that way:
public int SelectedIndex
{
get { return _selectedIndex; }
set
{
_selectedIndex = value;
OnPropertyChanged();
}
}
And in your XAML:
<ComboBox SelectedIndex="{Binding SelectedIndex,Mode=TwoWay}" ... >
When leaving the current page, the CollectionView
associated with the ItemsSource
property of the ComboBox
is purged. And because the ComboBox
IsSyncronizedWithCurrent
property is true by default, the SelectedItem
and SelectedValue
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 the Equals
operator on MyObject so that when comparing two MyObjects, the actual Id
properties are compared.
Another hint: If you do restructure your viewmodels and use SelectedValue
, use it only when SelectedValuePath=Id
where Id
is int
. If using a string key, bind to the Text
property of the ComboBox
instead of SelectedValue
.
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
public Role SelectedObject
{
get { return object; }
set
{
if (value != null)
{
if (!object.Equals(value))
{
object = value;
OnPropertyChanged(() => SelectedObject );
}
}
}
}
This should fix the issue.
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 had this problem with a ComboBox displaying a list of colors ( List<Brush> ).
Selecting a color was possible but it wasnt displayed when the selection closed (although the property was changed!)
The fix was overwriting the Equals(object obj) method for the type selected in the ComboBox (Brush), which wasnt simple because Brush is sealed. So i wrote a class EqualityBrush containing a Brush and implementing Equals:
public class EqualityBrush
{
public SolidColorBrush Brush { get; set; }
public override bool Equals(object o)
{
if (o is EqualityBrush)
{
SolidColorBrush b = ((EqualityBrush)o).Brush;
return b.Color.R == this.Brush.Color.R && b.Color.G == this.Brush.Color.G && b.Color.B == this.Brush.Color.B;
}
else
return false;
}
}
Using a List of my new EqualityBrush class instead of normal Brush class fixed the problem!
My Combobox XAML looks like this:
<ComboBox ItemsSource="{Binding BuerkertBrushes}" SelectedItem="{Binding Brush, Mode=TwoWay}" Width="40">
<ComboBox.Resources>
<DataTemplate DataType="{x:Type tree:EqualityBrush}">
<Rectangle Width="20" Height="12" Fill="{Binding Brush}"/>
</DataTemplate>
</ComboBox.Resources>
</ComboBox>
Remember that my "Brush"-Property in the ViewModel now has to be of Type EqualityBrush!