WPF:将列表绑定到列表框

发布于 2024-11-08 13:47:36 字数 740 浏览 0 评论 0原文

我有一个类:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

初与友歌 2024-11-15 13:47:36

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


编辑:

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

这正是引入 ObservableCollection 类的原因...ObservableCollection 实现了 INotifyCollectionChanged,这使得它可以在以下情况时通知 UI:添加/删除/替换项目。 List 不会触发任何通知,因此 UI 无法检测列表内容何时发生更改。

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

Your property has to be public, or the binding engine won't be able to access it.


EDIT:

After changing list to ObservableCollection and removing the NotifyPropertyChanged handler everything works.

That's precisely why the ObservableCollection<T> class was introduced... ObservableCollection<T> implements INotifyCollectionChanged, 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 of List<T> as before, so it reuses the same ICollectionView as the ItemsSource, and the content of the ListBox isn't refreshed.

荆棘i 2024-11-15 13:47:36

第一个想法是您正在尝试绑定到私人成员。这显然是不对的。

First thought is that you're trying to bind to a private member. That certainly doesn't seem right.

谁许谁一生繁华 2024-11-15 13:47:36

我认为问题在于,尽管您通知绑定框架属性已更改,但属性的实际值保持不变。也就是说,虽然列表框可能会重新评估其 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 属性配合使用 - 我只是推测!

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.

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

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!

一抹淡然 2024-11-15 13:47:36

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

ObservableCollections send CollectionChanged events not PropertyChanged events

黎歌 2024-11-15 13:47:36

通过发出信号,

NotifyPropertyChanged("bList");

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

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

CollectionChanged

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

By signaling

NotifyPropertyChanged("bList");

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

CollectionChanged

notifications that the collection items have changed, which is what you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文