Combobox binding itemsource to custom list and selecteditem to an instance of that list doesn't work

前端 未结 3 1833
轮回少年
轮回少年 2021-01-13 20:19

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)

相关标签:
3条回答
  • 2021-01-13 20:40

    A couple things, first you are binding to Grade and your property is called MyGrade. Second you are instantiating different objects for grade in the Grades list and using different objects to assign to each person, you want to use the same objects if you want them to map 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] });
    

    Lastly you might want to make the Grades collection an ObservableCollection as well if you are going to bind it to the UI. Also it seems a bit odd that your RaisePropertyChanged doesn't take in the name of the property.

    There may be other mistakes as well but that is what jumped out to me right away.

    0 讨论(0)
  • 2021-01-13 20:45

    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); 
      }
      
    0 讨论(0)
  • 2021-01-13 20:46

    Please make sure you have no binding errors in the first place. You can verify this by opening up the output window in Visual studio and check you have no errors messages relating to binding expressions.

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

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

    Below is a sample snippet of how one would achieve this:

    <ListView
        x:Name="listView"
        ItemsSource="{Binding People}"
        DisplayMemberPath="Name" />
    <ComboBox 
        ItemsSource="{Binding Grades}" 
        SelectedItem="{Binding SelectedItem.MyGrade, ElementName=listView}" 
        DisplayMemberPath="Name"/>
    
    0 讨论(0)
提交回复
热议问题