Combining the objects of binding to the user list and selecteditem instance of this list does not work

I tried really different ways to do my list work, but I was still stuck :(

Here is a very simplified version of my application: (just edited, sorry for the errors)

<ListView ItemsSource="{Binding People}" SelectedItem="{Binding SelectedPerson}"/> <ComboBox ItemsSource="{Binding Grades}" SelectedItem="{Binding SelectedPerson.MyGrade}" DisplayMemberPath="Name"/> 

And the code behind:

 public class Person { private string name; public string Name { get { return name; } set { if (name != value) { name = value; NotifyPropertyChanged("Name"); } } } private Grade myGrade; public Grade MyGrade { get { return myGrade; } set { if (myGrade != value) { myGrade = value; NotifyPropertyChanged("MyGrade"); } } } //-- INotifyPropertyChanged implementation } public class Grade { private string name; public string Name { get { return name; } set { if (name != value) { name = value; NotifyPropertyChanged("Name"); } } } private int prop; public int Prop { get { return prop; } set { if (prop != value) { prop = value; NotifyPropertyChanged("Prop"); } } } //-- INotifyPropertyChanged implementation } public partial class MainWindow : Window { public ObservableCollection<Person> People { get; set; } public ObservableCollection<Grade> Grades { get; set; } private Person selectedPerson; public Person SelectedPerson { get { return selectedPerson; } set { if (selectedPerson != value) { selectedPerson = value; NotifyPropertyChanged("SelectedPerson"); } } } public MainWindow() { InitializeComponent(); this.DataContext = this; People = new ObservableCollection<Person>(); Grades = new ObservableCollection<Grade>(); Grades.Add(new Grade() { Name = "Grade 1", Prop = 1 }); Grades.Add(new Grade() { Name = "Grade 2", Prop = 2 }); People.Add(new Person() { Name = "guy 1", MyGrade = Grades[0] }); People.Add(new Person() { Name = "guy 2", MyGrade = Grades[0] }); People.Add(new Person() { Name = "guy 3", MyGrade = Grades[1] }); } //-- INotifyPropertyChanged implementation } 

The problem is that combobox is still empty when I select an item from the list. The data source is in order (if I click on the combo box, I see "class 1" and "class 2"). I think there is something implicit to say that Person.Grade is part of the Grades list, but I cannot find that.

I hope you help me;)

+3
c # data-binding wpf combobox selecteditem
source share
3 answers

Is SelectedItem an exact reference in memory as an item in an ItemsSource ?

By default, WPF will compare the SelectedItem with the items in the ItemsSource by reference, and if they are not the same link in memory, it will not return the corresponding element.

If you cannot do this in your code, the most common workarounds are:

  • Bind SelectedValue to value type instead of reference type and set SelectedValuePath

     <ComboBox ItemsSource="{Binding Grades}" SelectedValue="{Binding SelectedPerson.MyGrade.GradeId}" SelectedValuePath="GradeId" DisplayMemberPath="Name"/> 
  • Or, override .Equals() to ensure that two objects are considered equal when certain properties match, as opposed to being considered equal when a reference in memory matches.

     public override bool Equals(object obj) { if (obj == null || !(obj is Grade)) return false; return ((Grade)obj).GradeId == this.GradeId); } 
+5
source share

A couple of things, you first MyGrade attached to Grade , and your property is called MyGrade . Secondly, you create different objects for the class in the Grades list and use different objects to assign to each person, you want to use the same objects if you want them to display correctly, something like this:

 Grades.Add(new Grade() { Name = "Grade 1", Prop = 1 }); Grades.Add(new Grade() { Name = "Grade 2", Prop = 2 }); People.Add(new Person() { Name = "guy 1", MyGrade = Grades[0] }); People.Add(new Person() { Name = "guy 2", MyGrade = Grades[0] }); People.Add(new Person() { Name = "guy 3", MyGrade = Grades[1] }); 

Finally, you might want to make the Grades a ObservableCollection collection if you are going to bind it to the user interface. It also seems a little strange that your RaisePropertyChanged not accepting the property name.

There may be other mistakes, but this is what immediately jumped at me.

+2
source share

Please ensure that you do not have binding errors in the first place. You can verify this by opening the output window in Visual Studio and make sure that you do not have error messages related to binding expressions.

You should be able to easily detect this because the error message will contain the following text: BindingExpression path error

As an alternative approach, why don't you try and bind the selected ComboBox item directly to the selected item from the ListView.

The following is a snippet of an example of how this could be achieved:

 <ListView x:Name="listView" ItemsSource="{Binding People}" DisplayMemberPath="Name" /> <ComboBox ItemsSource="{Binding Grades}" SelectedItem="{Binding SelectedItem.MyGrade, ElementName=listView}" DisplayMemberPath="Name"/> 
0
source share

All Articles