Combobox绑定项目源到自定义列表和selecteditem到该列表的实例不工作 [英] Combobox binding itemsource to custom list and selecteditem to an instance of that list doesn't work

查看:134
本文介绍了Combobox绑定项目源到自定义列表和selecteditem到该列表的实例不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试了真正不同的方式使我的组合框工作,但我仍然卡住:(



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

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

后面的代码:

  public class Person 
{
私有字符串名称;
公共字符串名称
{
get {return name;}
set
{
if != value)
{
name = value;
NotifyPropertyChanged(Name);
}
}
}
$ b b private class myGrade;
public Grade MyGrade
{
get {return myGrade;}
set
{
if(myGrade!= value)
{
myGrade = value;
NotifyPropertyChanged(MyGrade);
}
}

}

// - INotifyPropertyChanged实现
}
public class Grade
{
私有字符串名称;
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实现
}
public partial class MainWindow:Window
{
public ObservableCollection< Person>人{get;组; }
public ObservableCollection< Grade>成绩{get;组; }

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(新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实现
}

问题是,当我在列表视图中选择一个项目时,组合框仍然为空。
itemsource是OK(如果我点击组合框,我可以看到1级和2级)。
我认为有一些东西缺失说 Person.Grade Grades 列表的一部分,



希望你能帮助我。)

解决方案

SelectedItem 在内存中是否与 ItemsSource 中的项目完全相同?



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



如果你不能这样做您的代码,最常见的解决方法是:




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

     < ComboBox ItemsSource ={Binding Grades}
    SelectedValue ={Binding SelectedPerson.MyGrade.GradeId}
    SelectedValuePath =GradeId
    DisplayMemberPath =Name/> ;


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

      return false;返回false。 

    return((Grade)obj).G​​radeId == this.GradeId);

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

    这篇关于Combobox绑定项目源到自定义列表和selecteditem到该列表的实例不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆