Search code examples
c#mvvmcomboboxselecteditemselectedvalue

Synchronizing two comboboxes bound to the same collection and to the same selected item


I have two comboboxes to represent a customer code and a customer name. Both are bound to the same collection of objects and to the same SelectedItem. I want to update the customer name when I select a customer code and vice versa.

I am using C# with the MVVM pattern. I have tried all the combination of SelectedItem and SelectedValue with selectedvaluepath but nothing seems to work.

These are my two combo boxes:

<ComboBox Name="CmbStockUnitCustomerCode" ItemsSource="{Binding CustomerCodeDtos}" 
          DisplayMemberPath="Code" SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}" 
          IsSynchronizedWithCurrentItem="True"></ComboBox>

<ComboBox Name="CmbStockUnitCustomerName" ItemsSource="{Binding CustomerCodeDtos}"
          DisplayMemberPath="Name" SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}" 
          IsSynchronizedWithCurrentItem="True"></ComboBox>

And these are the bound objects:

public CustomerDto SelectedCustomer
{
    get => _selectedcustomer;
    set
    {
        _selectedcustomer = value;
        RaisePropertyChanged("SelectedCustomer");
    }
}

public class CustomerDto
{
    public short Code { get; set; }
    public string Name { get; set; }

    public CustomerDto(short code, string name)
    {
        this.Code = code;
        this.Name = name;
    }
}
public ObservableCollection<CustomerDto> CustomerCodeDtos
{
    get => _databaseService.GetAllCustomers();
}              

When I update one of the comboboxes, I expect the other one to update to the corresponding value in the object CustomerDto, but nothing happens.


Solution

  • You're recreating your collection every time you reference it, so SelectedItem is referencing a different object. In effect, your two combo boxes are using different collections as ItemsSources. Change the code to

    public ObservableCollection<CustomerDto> CustomerCodeDtos
    {
        get 
        { 
           if(_customerCodes==null)
           {
              _customerCodes = _databaseService.GetAllCustomers();
           }
           return _customerCodes;
        }
    }