WPF:将列表绑定到ListBox

时间:2011-05-19 11:59:12

标签: c# wpf binding listbox observablecollection

我有一个班级:

public class A : INotifyPropertyChanged
{
    public List<B> bList { get; set; } 

    public void AddB(B b)
    {
        bList.Add(b);
        NotifyPropertyChanged("bList");
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

绑定(UserControl的DataContext是A的实例):

<ListBox ItemsSource="{Binding Path=bList}" />

显示元素,将新对象添加到List

后,ListBox不会更新

将列表更改为ObservableCollection并删除NotifyPropertyChanged处理程序后,一切正常。

为什么列表不起作用?

5 个答案:

答案 0 :(得分:16)

您的属性必须为public,否则绑定引擎将无法访问它。


编辑:

  

将列表更改为ObservableCollection并删除NotifyPropertyChanged处理程序后,一切正常。

这正是引入ObservableCollection<T>类的原因...... ObservableCollection<T>实现INotifyCollectionChanged,允许它在添加/删除/替换项目时通知UI。 List<T>不会触发任何通知,因此UI无法检测列表内容何时发生更改。

你引发PropertyChanged事件的事实确实刷新了绑定,但随后它意识到它与之前的List<T>实例相同,因此它重用了ICollectionView作为ItemsSourceListBox的内容未刷新。

答案 1 :(得分:0)

首先想到的是你正试图绑定到私人成员。这当然不对。

答案 2 :(得分:0)

我认为问题在于,虽然您通知绑定框架该属性已更改,但该属性的实际值仍然相同。也就是说,尽管列表框可能会重新评估其ItemsSource绑定的值,但它会发现它仍然与之前的对象实例相同。例如,假设列表框以与下面类似的方式对属性更改事件作​​出反应。

private void OnItemsSourceBindingChanged()
{
    var newValue = this.EvaluateItemsSourceBinding();
    if (newValue != this.ItemsSource) //it will be equal, as its still the same list
    {
        this.AddNewItems();
    }
}

在您的示例中,这意味着它不会重新评估项目。

注意:我不知道列表框如何与ItemsSource属性一起使用 - 我只是在推测!

答案 3 :(得分:0)

ObservableCollections发送CollectionChanged个事件而非PropertyChanged事件

答案 4 :(得分:0)

通过发信号通知

NotifyPropertyChanged("bList");

你基本上是说你有一个新的 列表 对象,而不是列表的内容已经改变。

如果将类型更改为ObservableCollection,则集合会自动发送

CollectionChanged

集合 项目 的通知已更改,这就是您想要的。