Reputation: 13992
I have a ComboBox
bound to a list of people in a simple ViewModel
. The SelectedPerson is set in the constructor of the ViewModel, but when I run the application, the ComboBox is not set with its initial value. What am I doing wrong?
Notice that two instances of the MyPerson
class should be considered equal when they have the same Id.
Unfortunately, I cannot modify the MyPerson
to override Equals (it's third party).
The only option I've seen so far is to user the Adapter pattern to wrap the instances of this class and implement a custom Equals method there.
I feel that there should be a better method that is native to WPF to match items from a list by some kind of "key". In my case, the list of items and the selected item come from different sources, and that's why they have an Id property acting as a primary key.
I've played with SelectedValue and SelectedValuePath, but nothing works.
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:Test"
mc:Ignorable="d"
x:Name="Root"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<vm:MainViewModel />
</Window.DataContext>
<ComboBox ItemsSource="{Binding People}" SelectedItem="{Binding SelectedPerson}" SelectedValuePath="Id"
DisplayMemberPath="Name"
SelectedValue="{Binding SelectedPerson}" />
</Window>
And this ViewModel as DataContext:
public class MainViewModel
{
public MainViewModel()
{
SelectedPerson = new MyPerson { Name = "Mary", Id = 1 };
}
public MyPerson SelectedPerson { get; set; }
public IEnumerable<MyPerson> People { get; } = new List<MyPerson>()
{
new MyPerson() {Name = "Mary", Id = 1 },
new MyPerson() {Name = "John", Id = 2 },
};
}
public class MyPerson
{
public string Name { get; set; }
public int Id { get; set; }
}
Upvotes: 0
Views: 87
Reputation: 190
The problem is that the new object you create here
SelectedPerson = new MyPerson { Name = "Mary", Id = 1 };
isnt' the same as in your list so the Equals
method would return False
in all cases!
As someone else already suggested, you have to get the real object that is in the list by doing this:
public MainViewModel(){
SelectedPerson = People.First(x=> x.Name.Equals("Mary")); //Or: x.Id == 1
}
But there is also another solution: You can override the Equals
function in your MyPerson
class, so that every MyPerson
instance with the same Name
and/or Id
would indeed be seen as the same person.
EDIT
As you're using ViewModels in your project, it would be better if you had a ViewModel for the MyPerson
class too. It would solve your problems and make your design better!
Upvotes: 1
Reputation: 8573
Change
public MainViewModel()
{
SelectedPerson = new MyPerson { Name = "Mary", Id = 1 };
}
To
public MainViewModel()
{
SelectedPerson = People.ElementAt(0);
}
Or if ou want by name:
public MainViewModel()
{
SelectedPerson = People.First(x=> x.Name=="Mary");
}
Upvotes: 0