I tried really different ways to make my combobox working but I'm still stuck :(
Here is a very simplified version of my app : (just edited, sorry for mistakes)
<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 the combobox is still empty when I select an item in the listview.
The itemsource is OK (If I click on the combobox, I can see "grade 1" and "grade 2").
I think there is something missing to tell "the Person.Grade
is part of the Grades
list" but I cannot find what.
Hope you can help me ;)
Is the SelectedItem
the exact same reference in memory as the item in the ItemsSource
?
By default, WPF will compare the SelectedItem
to the items in the ItemsSource
by reference, and if they're not the same reference in memory, it will return no matching item.
If you are unable to do this in your code, the most common workarounds are to either:
Bind the SelectedValue
to a value type instead of a reference type, and set the SelectedValuePath
<ComboBox ItemsSource="{Binding Grades}"
SelectedValue="{Binding SelectedPerson.MyGrade.GradeId}"
SelectedValuePath="GradeId"
DisplayMemberPath="Name"/>
Or override the .Equals()
to ensure the two objects are considered equal when specific properties match, as opposed to being considered equal when the reference in memory matches.
public override bool Equals(object obj)
{
if (obj == null || !(obj is Grade))
return false;
return ((Grade)obj).GradeId == this.GradeId);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With