基本上,我想知道它在这里的实际效率如何。
示例代码:
void GetItems()
{
foreach (var item in items)
myObservableCollection.Add(item);
}
这不会每次都触发 CollectionChanged 事件,导致 UI 每次都必须刷新吗?还是这样做是为了等待 GetItems 函数完成?
基本上,WPF 似乎处理得很好,我想知道他们是如何做到的。
基本上,我想知道它在这里的实际效率如何。
示例代码:
void GetItems()
{
foreach (var item in items)
myObservableCollection.Add(item);
}
这不会每次都触发 CollectionChanged 事件,导致 UI 每次都必须刷新吗?还是这样做是为了等待 GetItems 函数完成?
基本上,WPF 似乎处理得很好,我想知道他们是如何做到的。
优化性能:数据绑定提供了有关如何解决数据绑定的一些背景知识,包括不同项目来源的性能影响。查看Binding to an ItemsSource部分。
考虑一个场景,您有一个 CLR List 对象,该对象包含您希望在 ListBox 中显示的员工列表。要在这两个对象之间创建对应关系,您需要将员工列表绑定到 ListBox 的 ItemsSource 属性。但是,假设您有一位新员工加入您的团队。您可能会认为,为了将这个新人插入到绑定的 ListBox 值中,您只需将此人添加到您的员工列表中,并期望数据绑定引擎自动识别此更改。
这种假设将被证明是错误的;实际上,更改不会自动反映在 ListBox 中。这是因为 CLR List 对象不会自动引发集合更改事件。为了让 ListBox 接受更改,您必须重新创建员工列表并将其重新附加到 ListBox 的 ItemsSource 属性。虽然此解决方案有效,但它会带来巨大的性能影响。每次将 ListBox 的 ItemsSource 重新分配给一个新对象时,ListBox 首先会丢弃其先前的项目并重新生成其整个列表。如果您的 ListBox 映射到复杂的 DataTemplate,性能影响会被放大。
这个问题的一个非常有效的解决方案是让你的员工列表成为一个 ObservableCollection。ObservableCollection 对象引发数据绑定引擎可以接收的更改通知。该事件无需重新生成整个列表即可从 ItemsControl 添加或删除项目。
1 个项目的更新时间(毫秒)
- 到 CLR 列表对象 = 1656 毫秒
- 到 ObservableCollection = 20 ms
WPF 从不直接绑定到集合。如果将集合指定为绑定源,WPF 实际上会绑定到集合的默认视图。
集合视图是绑定源集合之上的一个层,它允许您基于排序、过滤和分组查询来导航和显示源集合,而无需更改底层源集合本身。集合视图还维护指向集合中当前项目的指针。如果源集合实现 INotifyCollectionChanged 接口,则由 CollectionChanged 事件引发的更改将传播到视图。
每次更改都会触发该事件。
GUI 不必每次都做出反应和刷新,它可以推迟。
我知道 WinForms 会对此进行优化,我认为 WPF 也有类似的方法。
如果您想查看 UI 请求新结果的频率,将其公开为公共属性,并在 myObservableCollection 的公共属性的 get(评估器)中放置一个调试行。