question

Sarah-3412 avatar image
0 Votes"
Sarah-3412 asked HuiLiu-MSFT commented

Binding a WPF ComboBox to ObservableCollection

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-wpf
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi,@Sarah-3412. The error System.NullReferenceException: 'Object reference not set to an instance of an object.' means your object is not instantiated. What is the definition of your CityView and CountryValue? Could you show the relevant code?
I made the following example based on your code. Combobox is bound to a view of a collection of ClassA, why is the type of SelectedCountry defined as ClassB?

0 Votes 0 ·

Hi,@ Sarah-3412. Did my answer solve your problem? If so, you could accept it as the answer. It's helpful for community members with similar questions.

0 Votes 0 ·

1 Answer

HuiLiu-MSFT avatar image
0 Votes"
HuiLiu-MSFT answered

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 to enable e-mail notifications if you want to receive the related email notification for this thread. 


image.png (9.1 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.