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 处理程序后,一切正常。
为什么列表不起作用?
你的属性必须
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
集合项已更改的通知,这是您想要的。