ObservableCollection快速填充但缓慢的绑定可视化

本文关键字:缓慢 绑定 可视化 填充 ObservableCollection | 更新日期: 2023-09-27 18:32:29

我有一个ObservableCollection<T>可以容纳很多物品。数据将使用后台工作者异步接收(这工作正常且快速)。

但是,如果我尝试将巨大的集合绑定到BackgroundWorkerCompleteTask上的列表框/列表视图(无论什么),可视化将花费大量时间,GUI将挂起,直到绑定/可视化完成。

任何想法如何提高性能或防止这种行为?

void bgGetData_DoWork(object sender, DoWorkEventArgs e)
{
    HugeData();
}
 void bgGetData_ProgressChanged(object sender, ProgressChangedEventArgs e)
 {
     devices.Add((ServiceReference1.Device)e.UserState);
 }
private void HugeData()
{
     foreach (ServiceReference1.Device dev in Proxy.client.GetHugeDate())
     {
         bgGetData.ReportProgress(0, dev);
     }
}

数据受以下约束:

myControl.ItemsSource = devices;

谢谢。

ObservableCollection<T>快速填充但缓慢的绑定可视化

我在集合数据以及为集合中的项目设置 GroupNames 方面都遇到了非常相似的问题(我想允许空组,所以我手动更新 PropertyGroupDescriptor.GroupNames)。

事实证明,当添加到 ObservableCollection 时,您会在添加的每一行上触发 CollectionChanged 事件,如果您更改组,则会更新组和每个组的行。

解决方案是在集合上使用 AddRange,遗憾的是它不存在,并且您无法从包含组名称的 ObservableCollection 继承,因为它来自保存数据的集合的 PropertyGroupDescriptor ...但。。。您可以使用反射在基础项目上获得最隐蔽的杂物。

所以,我提出了我非常讨厌的组名更新代码:-

    public void CheckGroups(ObservableCollection<Object> GroupNames) {
        var lBindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
        if (mHasUpdates) {
            var lHashC = new HashSet<Object>(GroupNames);
            var lHashN = new HashSet<Object>(mGroupList);
            var lAdd = lHashN.Except(lHashC).ToList();
            var lRemove = lHashC.Except(lHashN).ToList();
            if (lAdd.Count > 0 || lRemove.Count > 0) {
                var lType = GroupNames.GetType();
                var lProp = lType.GetProperty("Items", lBindingFlags);
                var lItems = (List<Object>)lProp.GetValue(GroupNames, null);
                var lMethod = lType.GetMethod("OnCollectionChanged", lBindingFlags, null, new Type[] { typeof(NotifyCollectionChangedEventArgs) }, null);
                var lArgs = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
                if (lAdd.Count > 0) lItems.AddRange(lAdd);
                if (lRemove.Count > 0) lItems.RemoveAll(R => lRemove.Contains(R));
                lMethod.Invoke(GroupNames, new Object[] { lArgs });
            }
        }
    }