Combobox绑定itemssource到自定义列表和选定项目到该列表的实例不起作用

时间:2013-12-17 22:24:35

标签: c# wpf data-binding combobox selecteditem

我尝试了不同的方法让我的组合框工作但我仍然卡住:(

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

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

背后的代码:

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
}

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

希望你能帮助我;)

3 个答案:

答案 0 :(得分:6)

SelectedItem内存与ItemsSource中的项完全相同吗?

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

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

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

    <ComboBox ItemsSource="{Binding Grades}" 
              SelectedValue="{Binding SelectedPerson.MyGrade.GradeId}" 
              SelectedValuePath="GradeId"
              DisplayMemberPath="Name"/>
    
  • 或覆盖.Equals()以确保在特定属性匹配时认为两个对象相等,而不是在内存中的引用匹配时视为相等。

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

答案 1 :(得分:2)

有几件事,首先你绑定到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没有接受财产的名称似乎有点奇怪。

也可能有其他错误,但这就是马上跳出来的。

答案 2 :(得分:0)

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

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

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

以下是如何实现此目标的示例摘录:

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