SuperJMN
SuperJMN

Reputation: 13992

ComboBox not autoselecting initial value

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

Answers (2)

Karina K.
Karina K.

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 MyPersonclass too. It would solve your problems and make your design better!

Upvotes: 1

Magnetron
Magnetron

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

Related Questions