Search code examples
wpfmvvmbindingcomboboxselecteditem

ComboBox SelectedItem initial value not from ItemsSource


I cannot understand the behavior of the combobox.

I have an edit view to edit existing Order data. Here is my VM of some part of Order data:

public class OrderDataViewModel : ViewModelBase, IOrderDataViewModel
{
    private readonly ICustomersListProviderService _customersListProviderService;
    private readonly Order _order;

    public OrderDataViewModel(Order order, ICustomersListProviderService customersListProviderService)
    {
        Assign.IfNotNull(ref _order, order);
        Assign.IfNotNull(ref _customersListProviderService, customersListProviderService);
    }

    public DateTime CreationDate
    {
        get { return _order.CreationDate ?? (_order.CreationDate = DateTime.Now).Value; }
        set
        {
            if (_order.CreationDate == value) return;

            _order.CreationDate = value;
            OnPropertyChanged();
        }
    }

    public Customer Customer
    {
        get { return _order.Customer; }
        set
        {
            if (_order.Customer == value) return;

            _order.Customer = value;
            OnPropertyChanged();
        }
    }


    private IList<Customer> _customersList;
    public IList<Customer> CustomersList
    {
        get { return _customersList ?? (_customersList = _customersListProviderService.GetAllCustomers().ToList()); }
    }
}

And XAML binding:

 <ComboBox Grid.Row="2" Grid.Column="1"
                        SelectedItem="{Binding OrderDataViewModel.Customer}"
                        DisplayMemberPath="Name"
                        ItemsSource="{Binding OrderDataViewModel.CustomersList}"
                        />

Description. Order comes from the database by the Repository, _customersListProviderService gets all customers from database also. I know that maybe it could be done better, but it's not the point of the question.

And... the issue is. After loading a window, my combobox has items collection filled (dropdown list is not empty) but the value is not set (its blank). Checking SelectedItem by code-behind results with null. I read a lot and found out, that you cannot set SelectedItem of combobox to the item that is not in ItemsSource.

Ok, my workaround was to change the Customer getter to:

public Customer Customer
        {
            get
            { return CustomersList.Single(c => c.Id == _order.Customer.Id); }
            set
            {
                if (_order.Customer == value) return;

                _order.Customer = value;
                OnPropertyChanged();
            }
        } 

now it works, but it does not look good to me.

Is there any better solution?


Solution

  • you can override Equals() and GetHashCode() in your entities and return Id.Equals() and Id.GetHashCode() respectively