Binding a WPF ComboBox to ObservableCollection

Sarah 186 Reputation points
2022-05-10T10:56:38.47+00:00

I usea ComboBox that doesn't seem to update the SelectedItem.

<ComboBox ItemsSource="{Binding Path=CountryEntries}"
          DisplayMemberPath="Country"
          SelectedValuePath="Country"
          SelectedValue="{Binding Path=CountryValue}"
          SelectedItem="{Binding Path=SelectedCountry}"/>

The ItemsSource of ComboBox is bound to a property "CountryEntries" on ViewModelClassB.

public class ViewModelClassB : INotifyPropertyChanged
{


    private readonly CollectionView countryEntries = new CollectionView(ListOfCountry()); // Type of ListOfCountry() is ObservableCollection<ClassA>
    public CollectionView CountryEntries
    {
        get
        {
            return countryEntries;
        }
    }

    public ClassB SelectedCountry
    {
        get => selectedCountry;
        set
        {
            this.selectedCountry = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(CityView));
        }
    }
}


public class ClassA : INotifyPropertyChanged
{
    public string Country { get; set; }
    public string City { get; set; }
}


public class ClassB : INotifyPropertyChanged
{
    public string Pro1 { get; set; }
    public string Pro2 { get; set; }
    public string CountryValue{ get; set; }

}

I get the following error:

System.NullReferenceException: 'Object reference not set to an instance of an object.'

SelectedCountry.get returned null.

I've checked my code several times and can't seem to find anything that I'm doing wrong.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,784 questions
{count} votes

Accepted answer
  1. Hui Liu-MSFT 48,571 Reputation points Microsoft Vendor
    2022-05-11T03:05:57.937+00:00

    MainWindow.xaml:

    <Grid>  
            <ComboBox ItemsSource="{Binding Path=CountryEntries}" Width="200" Height="60"  
               DisplayMemberPath="Country"   
               SelectedValuePath="Country"  
               SelectedItem="{Binding Path=SelectedCountry,  Mode=TwoWay}"/>  
        </Grid>  
    

    MainWindow.xaml.cs:

    using System.Collections.ObjectModel;  
    using System.ComponentModel;  
    using System.Runtime.CompilerServices;  
    using System.Windows;  
    using System.Windows.Data;  
    
    namespace ComboboxFilter  
    {  
      public partial class MainWindow : Window  
      {  
        public MainWindow()  
        {  
          InitializeComponent();  
          DataContext=new ViewModelClassB();  
        }  
      }  
      public class ViewModelClassB : INotifyPropertyChanged  
      {  
        private ObservableCollection<ClassA> listOfCountry;  
        public ObservableCollection<ClassA> ListOfCountry  
        {  
          get  
          {  
            return listOfCountry;  
          }  
          set { listOfCountry=value; OnPropertyChanged("ListOfCountry");}  
        }  
        private readonly ICollectionView countryEntries ;   
        public ICollectionView CountryEntries  
        {  
          get  
          {  
            return countryEntries;  
          }  
        }  
        public ViewModelClassB()  
        {  
          listOfCountry=new ObservableCollection<ClassA>();  
          listOfCountry.Add(new ClassA() {  City="Beijing",  Country="China"});  
          listOfCountry.Add(new ClassA() {  City= "New York",  Country= "United States" });  
          listOfCountry.Add(new ClassA() {  City= "Paris ",  Country= "France" });  
          countryEntries=CollectionViewSource.GetDefaultView(listOfCountry);  
        }  
        private ClassB selectedCountry;  
        public ClassB SelectedCountry  
        {  
          get => selectedCountry;  
          set  
          {  
            this.selectedCountry = value;  
            OnPropertyChanged("SelectedCountry");  
            //OnPropertyChanged(nameof(CityView));  
          }  
        }  
        public event PropertyChangedEventHandler PropertyChanged;  
        internal void OnPropertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));  
      }  
      public class ClassA   
      {  
        public string Country { get; set; }  
        public string City { get; set; }  
      }  
      public class ClassB   
      {  
        public string Pro1 { get; set; }  
        public string Pro2 { get; set; }  
        public string CountryValue { get; set; }  
      }  
    }  
    

    The result:

    200806-image.png


    If the response is helpful, please click "Accept Answer" and upvote it.
     Note: Please follow the steps in our [documentation][5] to enable e-mail notifications if you want to receive the related email notification for this thread. 

    [5]: https://learn.microsoft.com/en-us/answers/articles/67444/email-notifications.html

    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.