INotifyCollectionChanged——它多久触发一次(以及它们如何使其如此高效/快速)?

发布于 2024-12-07 12:53:20 字数 286 浏览 1 评论 0原文

基本上,我想知道它在这里实际上是如何有效的。

示例代码:

void GetItems()
{
    foreach (var item in items)
        myObservableCollection.Add(item);
}

这不会每次都会触发 CollectionChanged 事件,导致 UI 每次都必须刷新吗?或者它是否这样做,以便等待直到 GetItems 函数完成?

基本上,WPF 似乎处理得很好,我想知道他们是如何做到的。

Basically, I'm wondering how it is actually efficient here.

Sample code:

void GetItems()
{
    foreach (var item in items)
        myObservableCollection.Add(item);
}

Won't this fire off the CollectionChanged event every time causing the UI to have to refresh everytime? Or does it do it so that it waits til the GetItems function is done?

Basically, it seems that WPF handles it very well, and I'm wondering how they did that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

迷鸟归林 2024-12-14 12:53:20

优化性能:数据绑定提供了有关如何解析数据绑定的一些背景知识,包括不同项目来源的性能影响。请查看绑定到 ItemsSource 部分。

考虑这样一个场景,您有一个 CLR List 对象,其中包含
要在列表框中显示的员工列表。创建一个
这两个对象之间的对应关系,您将绑定您的员工
list 到 ListBox 的 ItemsSource 属性。然而,假设你
有一位新员工加入您的团队。你可能会认为按照顺序
要将这个新人插入到您绑定的 ListBox 值中,您可以
只需将此人添加到您的员工列表中并期望此更改
被数据绑定引擎自动识别。

这个假设被证明是错误的;事实上,这种改变不会
自动反映在列表框中。这是因为 CLR
列表对象不会自动引发集合更改
事件。为了让列表框接受更改,您可以
必须重新创建您的员工列表并将其重新附加到
ListBox 的 ItemsSource 属性。虽然这个解决方案有效,但它
引入了巨大的性能影响。每次重新分配
ListBox的ItemsSource到一个新对象,ListBox先扔掉
其以前的项目并重新生成其整个列表。性能
如果您的列表框映射到复杂的数据模板,影响会放大。

解决这个问题的一个非常有效的方法是让你的员工
列出一个 ObservableCollection。 ObservableCollection 对象
引发数据绑定引擎可以发出的更改通知
收到。该事件从 ItemsControl 添加或删除项目
无需重新生成整个列表。

1 项的更新时间(毫秒)

  • 到 CLR 列表对象 = 1656 毫秒
  • 到 ObservableCollection = 20 毫秒

WPF 从不直接绑定到集合。如果将集合指定为绑定源,WPF 实际上会绑定到该集合的 默认值查看

集合视图是绑定源集合之上的一层
允许您基于以下内容导航和显示源集合
排序、过滤和分组查询,无需更改
底层源集合本身。集合视图还维护
指向集合中当前项的指针。如果源
集合实现了 INotifyCollectionChanged 接口,
CollectionChanged 事件引发的更改将传播到
意见。

Optimizing Performance: Data Binding provides some background on how data bindings are resolved, including the performance implications of different items sources. Take a look at the Binding to an ItemsSource section.

Consider a scenario in which you have a CLR List object that holds
a list of employees that you want to display in a ListBox. To create a
correspondence between these two objects, you would bind your employee
list to the ItemsSource property of the ListBox. However, suppose you
have a new employee joining your group. You might think that in order
to insert this new person into your bound ListBox values, you would
simply add this person to your employee list and expect this change to
be recognized by the data binding engine automatically.

That assumption would prove false; in actuality, the change will not
be reflected in the ListBox automatically. This is because the CLR
List object does not automatically raise a collection changed
event. In order to get the ListBox to pick up the changes, you would
have to recreate your list of employees and re-attach it to the
ItemsSource property of the ListBox. While this solution works, it
introduces a huge performance impact. Each time you reassign the
ItemsSource of ListBox to a new object, the ListBox first throws away
its previous items and regenerates its entire list. The performance
impact is magnified if your ListBox maps to a complex DataTemplate.

A very efficient solution to this problem is to make your employee
list an ObservableCollection. An ObservableCollection object
raises a change notification which the data binding engine can
receive. The event adds or removes an item from an ItemsControl
without the need to regenerate the entire list.

Update time for 1 item (ms)

  • To a CLR List object = 1656 ms
  • To an ObservableCollection = 20 ms

WPF never binds directly to a collection. If you specify a collection as a binding source, WPF actually binds to the collection's default view.

A collection view is a layer on top of a binding source collection
that allows you to navigate and display the source collection based on
sort, filter, and group queries, without having to change the
underlying source collection itself. A collection view also maintains
a pointer to the current item in the collection. If the source
collection implements the INotifyCollectionChanged interface, the
changes raised by the CollectionChanged event are propagated to the
views.

意犹 2024-12-14 12:53:20

每次更改都会触发该事件。

GUI 不必每次都做出反应和刷新,它可以推迟。
我知道WinForms会对此进行优化,我认为WPF也有类似的方法。

The event will fire for every change.

The GUI does not have to react and refresh every time, it can postpone that.
I know WinForms will optimize this, I think WPF has a similar approach.

茶花眉 2024-12-14 12:53:20

如果您想查看 UI 请求新鲜结果的频率,请将其公开为公共属性,并将调试行放入 myObservableCollection 的公共属性的 get(评估器)中。

If you want to see how often the UI requests the fresh results expose it as a public property and put a debug line in the get (assessor) of the public property for myObservableCollection.

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