WPF:将列表绑定到列表框

本文关键字:列表 绑定 WPF | 更新日期: 2023-09-27 17:56:50

我有一个类:

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

显示元素,将新对象添加到列表后不会更新列表框

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

为什么列表不起作用?

WPF:将列表绑定到列表框

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


编辑:

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

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

引发 PropertyChanged 事件的事实确实刷新了绑定,但随后它意识到它与以前是相同的List<T>实例,因此它重用与ItemsSource相同的ICollectionView,并且ListBox的内容不会刷新。

第一个想法是你正在尝试绑定到私有成员。这似乎当然不对。

我认为

问题是,尽管您通知绑定框架属性已更改,但属性的实际值保持不变。 也就是说,尽管列表框可能会重新计算其 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 属性一起工作 - 我只是猜测!

ObservableCollections send CollectionChanged 事件而不是 PropertyChanged 事件

通过信令

NotifyPropertyChanged("bList");

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

如果将类型更改为"可观察集合",则集合会自动发送

CollectionChanged

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