Wpf DataVirtualization

本文关键字:DataVirtualization Wpf | 更新日期: 2023-09-27 18:06:00

我正在尝试加载一个相当大的项目列表到WPF DataGrid。问题是:速度慢得令人痛苦。现在我的清单上有大约2万个项目,而且要花很长时间(嗯……在我的最新版本中,大约需要10秒,但这还不够好)。我在过去的几天里一直在努力,但我没有找到一个真正有效的解决方案。

1)当然UI虚拟化是启用的(这不再是问题了)

2)我还尝试了Bea Stollnitz在这里和其他人描述的一些解决方案。这些解决方案很棒,但不适合我,因为我的集合必须在运行时更新,过滤和排序,而无需重新加载集合。我发现的解决方案只适用于IList实现…我需要一个Observable集合来保持我的项目是最新的。

这是一种情况:我确实有一个我的领域数据对象的可观察对象集合(它通过WCF异步更新)。我确实有一个ViewModel用于包装域对象的列表项。当我打开视图时,我有第二个列表,它将为每个域对象填充ViewModel实例。这才是真正的问题。由于"目标"集合绑定到我的DataGrid,我必须将ViewModels的创建分派到UI线程中(否则。net对来自另一个线程的集合更改不太满意)。因此,我用20,000个视图模型创建调用污染了Dispatcher队列。创建ViewModel非常便宜,但是我在调度队列中仍然有20,000个调用,同时DataGrid在同一线程中要求CPU来填充自己。

我的想法(不完全完成):因为我已经有了UI虚拟化的地方,我想创建ViewModels不是当我打开我的视图,但在飞行,然后我需要他们。当用户最初可以看到前20个条目时,我只需要创建20个viewmodel,而不是20,000个。我的问题是:我不知道该怎么做。这就是你的用武之地

我想有这样的东西(不是那样工作)。只是为了说明我的意思):

<DataGrid ItemsSource={Binding MyDomainOjectCollection}>
    <DataGrid.RowStyle>
        <Style>
            <Setter Property="DataContext" 
                    Value="{Binding DataContext, 
                            Converter={StaticResource  MyViewModelFactoryConverter}}">
            </Setter>
        </Style>
    </DataGrid.RowStyle>
</DataGrid>

它不一定是一个Converter,也可以是其他的东西,或者在后面的代码中完成。我也不在乎我所需要的是:直接绑定到DomainObject集合,动态创建相应的ViewModel,并使用刚刚创建的ViewModel而不是原始对象来填充单行。什么好主意吗?

Wpf DataVirtualization

淹没你的ObservableCollection和UI得到更新的每一个项目是问题,我认为。

应该使用BindingList。您可以在添加一系列项目时禁用其上的事件,如下所示:

BindingList.RaiseListChangedEvents = false;

将阻止UI接收任何事件。然后在批量添加之后,您可以使用:

BindingList.RaiseListChangedEvents = true;
BindingList.ResetBindings();

当我打开视图时,我有第二个列表,该列表将为每个域对象填充ViewModel实例。

很好,那应该是你过滤的ObservableCollection。

由于"目标"集合绑定到我的DataGrid,我必须将ViewModels的创建分派到UI线程

不,你不需要。ViewModel是一个非ui元素,它可以在任何线程上创建。将这些项添加到ObservableCollection中需要在UI线程上完成。所以你可以在任何你喜欢的地方创建所有的VM包装器,我建议你分批进行,然后将批处理填充到ObservableCollection中作为一个操作。现在我知道ObservableCollection被设置为一次只添加一个项目,但这很容易通过向它添加一个扩展方法来补救,如前面的SO答案所示。请注意,您只需要在UI线程上调用扩展方法,一旦有了扩展方法,您就可以逐个添加项了。

就我个人而言,我会像疯了一样不检索所有的数据,我想你已经分析了这个需求,无法避免它。但是您真的需要在客户机上进行过滤和排序吗?这不能通过向服务器发送数据,然后用适当的数据进行应答来实现吗?

无论如何,如果你必须获得所有的数据,那么我建议你分批进行(虽然20K项不是一个巨大的数量,但仍然是合理的)。这很容易做到,并且在视图模型中使用属性通知,您可以使已过滤的集合与已添加到源集合中的内容保持同步。

相关文章:
  • 没有找到相关文章