WPF:将列表绑定到ListBox

11

我有一个类:

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}" />

在添加新对象到列表后,元素会显示出来,但ListBox没有更新。

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

为什么列表没能正常工作?


1
请发布您的真实代码...您发布的代码无法工作,即使使用ObservableCollection也不行。而且NotifyPropertyChanged对您并没有任何改变,因为您没有使用它。 - Thomas Levesque
5个回答

16

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


编辑:

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

这就是为什么引入了ObservableCollection<T>类的原因... ObservableCollection<T>实现了INotifyCollectionChanged接口,可以在项被添加/移除/替换时通知UI。而List<T>不会触发任何通知,因此UI无法检测到列表内容已更改。

事实上,您引发PropertyChanged事件确实会刷新绑定,但随后它意识到它仍然是与之前相同的List<T>实例,因此它重用与ItemsSource相同的ICollectionView,而ListBox的内容未被刷新。


谢谢,它是公共的,我忘记在代码中写了。现在代码已经更改。 - Damian
感谢您解释为什么在数据绑定中使用ObservableCollection很有用。 - ebhh2001

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属性 - 我只是在推测!

0

通过信号传递

NotifyPropertyChanged("bList");

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

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

CollectionChanged

通知集合items已更改,这正是您想要的。


0

首先想到的是您正在尝试绑定到私有成员。这显然不太对。


谢谢,这是公开的,我忘记在代码中写了。现在代码已经更改了。 - Damian

0

ObservableCollections 发送 CollectionChanged 事件而不是 PropertyChanged 事件


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接