Combobox将itemsource绑定到自定义列表,将selecteditem绑定到该列表的实例不起作用

我尝试了不同的方法让我的combobox工作,但我仍然卡住了:(

这是我的应用程序的一个非常简化的版本:(刚编辑,抱歉错误)

  

而背后的代码:

 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 People { get; set; } public ObservableCollection 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(); Grades = new ObservableCollection(); 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 } 

问题是当我在列表视图中选择一个项目时,combobox仍然是空的。 itemsource是好的(如果我点击combobox,我可以看到“1级”和“2级”)。 我认为有一些东西不能告诉“ Person.GradeGrades列表的一部分”,但我找不到什么。

希望你能帮我 ;)

SelectedItemItemsSource的项目在内存中是否完全相同?

默认情况下,WPF会通过引用将SelectedItemItemsSource的项进行比较,如果它们在内存中不是相同的引用,则它将不返回任何匹配的项。

如果您无法在代码中执行此操作,则最常见的解决方法是:

  • SelectedValue绑定到值类型而不是引用类型,并设置SelectedValuePath

      
  • 或者覆盖.Equals()以确保在特定属性匹配时认为两个对象相等,而不是在内存中的引用匹配时被视为相等。

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

一些事情,首先你绑定到Grade ,你的财产叫做MyGrade 。 其次,您要在Grades列表中实例化等级的不同对象,并使用不同的对象分配给每个人,如果您希望它们正确映射,您希望使用相同的对象,如下所示:

 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] }); 

最后,如果要将它绑定到UI,您可能还希望将Grades集合设置为ObservableCollection 。 你的RaisePropertyChanged没有采用该属性的名称似乎有点奇怪。

可能还有其他错误,但这就是我立即跳出来的错误。

请确保首先没有绑定错误。 您可以通过在Visual Studio中打开输出窗口来validation这一点,并检查没有与绑定表达式相关的错误消息。

您应该能够轻松发现这些,因为错误消息将包含以下文本: BindingExpression路径错误

作为替代方法,为什么不尝试将ComboBox所选项直接与ListView中的选定项绑定。

下面是一个如何实现这一目标的示例片段: