WPF:将列表绑定到列表框
我有一个类:
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 处理程序后,一切正常。
为什么该列表不起作用?
I have a class:
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));
}
}
}
And a binding (DataContext of UserControl is an instance of A):
<ListBox ItemsSource="{Binding Path=bList}" />
Elements are shown, the ListBox is not updated after new object is added to List
After changing list to ObservableCollection and removing the NotifyPropertyChanged handler everything works.
Why the list is not working?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您的属性必须是公共
,否则绑定引擎将无法访问它。编辑:
这正是引入
ObservableCollection
类的原因...ObservableCollection
实现了INotifyCollectionChanged
,这使得它可以在以下情况时通知 UI:添加/删除/替换项目。List
不会触发任何通知,因此 UI 无法检测列表内容何时发生更改。事实上,您引发
PropertyChanged
事件确实刷新了绑定,但随后它意识到它与之前相同的List
实例,因此它重用了相同的 < code>ICollectionView 作为ItemsSource
,并且ListBox
的内容不会刷新。Your property has to bepublic
, or the binding engine won't be able to access it.EDIT:
That's precisely why the
ObservableCollection<T>
class was introduced...ObservableCollection<T>
implementsINotifyCollectionChanged
, which allows it to notify the UI when an item is added/removed/replaced.List<T>
doesn't trigger any notification, so the UI can't detect when the content of the list has changed.The fact that you raise the
PropertyChanged
event does refresh the binding, but then it realizes that it's the same instance ofList<T>
as before, so it reuses the sameICollectionView
as theItemsSource
, and the content of theListBox
isn't refreshed.第一个想法是您正在尝试绑定到私人成员。这显然是不对的。
First thought is that you're trying to bind to a private member. That certainly doesn't seem right.
我认为问题在于,尽管您通知绑定框架属性已更改,但属性的实际值保持不变。也就是说,虽然列表框可能会重新评估其 ItemsSource 绑定的值,但它会发现它仍然是与之前相同的对象实例。例如,假设列表框对属性更改事件的反应与下面类似。
在您的示例中,这意味着它不会重新评估这些项目。
注意:我不知道列表框如何与 ItemsSource 属性配合使用 - 我只是推测!
I think that the problem is that, although you are notifying the binding framework that the property has changed, the actual value of the property remains the same. That is to say that although the listbox may reevaluate the value of its ItemsSource binding, it will find that it is still the same object instance as previously. For example, imagine that the listbox reacts by to the property changed event somehow similar to the below.
In your example, this would mean that it would not reevaluate the items.
Note: I do not know how the listbox works with the ItemsSource property - I'm just speculating!
ObservableCollections 发送 CollectionChanged 事件而不是 PropertyChanged 事件
ObservableCollections send CollectionChanged events not PropertyChanged events
通过发出信号,
您基本上是在说您有一个新的列表对象,而不是列表的内容已更改。
如果您将类型更改为 ObservableCollection,集合会自动发送
集合项目已更改的通知,这正是您想要的。
By signaling
you are basically saying you have a new list object, not that the content of the List has changed.
If you Change the type to ObservableCollection, the collections automatically sends
notifications that the collection items have changed, which is what you want.