我正在尝试将相当大的项目列表加载到 WPF DataGrid 中。问题是:它非常缓慢。现在,我的列表中有大约 20,000 个项目,而且需要很长时间(嗯……在我的最新版本中,大约需要 10 秒,但这还不够好)。最近几天我一直在研究它,但我没有找到真正有效的解决方案。
1)当然启用了UI虚拟化(这不再是问题了)
2)我还尝试了 Bea Stollnitz在这里和其他人描述的一些解决方案。这些解决方案很棒,但对我不起作用,因为我的集合必须在运行时更新、过滤和排序,而无需重新加载集合。我找到的解决方案仅适用于 IList 实现......我需要一个 Observable 集合来使我的项目保持最新。
情况就是这样:我确实有我的域数据对象的 Observable 集合(它通过 WCF 异步更新)。我确实有一个 ViewModel 用于包装域对象的列表项。当我打开视图时,我有第二个列表,其中将填充每个域对象的 ViewModel 实例。这是真正的问题。由于“目标”集合绑定到我的 DataGrid,我必须将 ViewModels 的创建分派到 UI 线程(否则 .Net 对来自另一个线程的集合更改不太满意)。所以我用 20,000 个视图模型创建调用污染了 Dispatcher 队列。创建 ViewModel 非常便宜,但调度程序队列中仍有 20,000 个调用,同时 DataGrid 要求同一线程中的 CPU 来填充自己。
我的想法(还没有完成):因为我已经有了 UI 虚拟化,所以我不想在打开视图时创建 ViewModel,而是在运行时需要它们。当用户最初可以看到前 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>
它不一定是转换器,也可以是其他东西或在后面的代码中完成。我不在乎。我需要的是:直接绑定到 DomainObject 集合,动态创建相应的 ViewModel,并使用刚刚创建的 ViewModel 而不是原始对象来填充单行。有任何想法吗?