哪个更好用:用于显示大量数据的 DataGrid 或 ListView?

Posted

技术标签:

【中文标题】哪个更好用:用于显示大量数据的 DataGrid 或 ListView?【英文标题】:What's better to use: a DataGrid or ListView for displaying large amounts of data? 【发布时间】:2011-08-30 16:29:05 【问题描述】:

我想在表格中显示 >50000 行。最好使用哪个控件:DataGrid 或 ListView(在详细信息视图中)?这些控件中哪一个的性能更好?

【问题讨论】:

为什么不显示分页数据而不是一起显示 > 50000 行。 这样的数字没有“更好”。最好是 50 行,这是您可以期望人们在不想卸载程序的情况下阅读的行数。 测试这两种解决方案并查看结果。我最近使用 DataGridView 来显示超过 300k 行 - 如果用户进行这样的数据选择 - 并且没有注意到任何性能问题(如果您禁用列的自动调整大小)。当然会有一些延迟,但对于如此大量的数据 - 可以接受。一切都取决于您的项目。 LOL +1 @mj82 表示“当然有一些延迟” 【参考方案1】:

正如 Hans 在对原始问题的评论中所说,它们的性能都将非常糟糕,只有在同时显示这么多行数据的疯狂时,您的用户肯定会感到不悦.

但是,如果这在您的应用程序中是不可避免的(并且您提供了非常很好的搜索功能),那么您应该强烈考虑使用 虚拟模式 选项,无论哪个控制你决定使用。这意味着您必须提供自己的数据管理操作,而不是依赖控件为您完成。优点是事情要快得多。正如documentation 所说:

虚拟模式专为处理大量数据而设计。当VirtualMode 属性为真时,您创建一个具有一定数量的行和列的DataGridView,然后处理CellValueNeeded event 以填充单元格。虚拟模式需要实现底层数据缓存,以根据用户的操作来处理 DataGridView 单元格的填充、编辑和删除。有关实现虚拟模式的更多信息,请参阅How to: Implement Virtual Mode in the Windows Forms DataGridView Control。

或者,对于ListView control:

VirtualMode 属性设置为true 会使ListView 进入虚拟模式。在虚拟模式下,正常的Items 集合未被使用。相反,ListViewItem 对象是根据 ListView 的需要动态创建的。

虚拟模式在许多情况下都很有用。如果ListView 对象必须从内存中的一个非常大的集合中填充,那么为每个条目创建一个ListViewItem 对象可能是一种浪费。在虚拟模式下,仅创建所需的项目。在其他情况下,ListViewItem 对象的值可能需要经常重新计算,并且对整个集合执行此操作会产生不可接受的性能。在虚拟模式下,只计算需要的项目。

为了使用虚拟模式,您必须处理RetrieveVirtualItem event,每次ListView 需要一个项目时都会引发该问题。此事件处理程序应创建属于指定索引的ListViewItem 对象。此外,VirtualListSize property 必须设置为虚拟列表的大小。

处理SearchForVirtualItem event 可以在虚拟模式下进行搜索。如果不处理此事件,FindItemWithTextFindNearestItem 方法将返回 null。

您可以处理CacheVirtualItems event 以维护ListViewItem 对象的缓存。如果创建ListViewItem 对象的计算或查找成本很高,则维护缓存可以提高性能。

如果View property设置为Tile,当VirtualMode设置为true时,该值将自动更改为LargeIcon。

在虚拟模式下,Items 集合被禁用。尝试访问它会导致InvalidOperationExceptionCheckedItems 集合和SelectedItems 集合也是如此。如果要检索选定或选中的项目,请改用 SelectedIndicesCheckedIndices 集合。

【讨论】:

我对此解决方案进行了一些研究,发现 WPF 中不存在虚拟模式:/ WPF 中有任何方法可以解决此问题 @Akrem:这很有趣。你的问题根本没有说任何关于 WPF 的内容。事实上,我将其标记为winforms,因为它看起来像是在谈论 WinForms 控件,而不是 WPF 控件。我想那是个错误。不,我不知道 WPF。如果您标记了 WPF 问题,我将不会回答。 @Akrem:啊,对不起。我以为你是最初的提问者。我真的对WPF一无所知,但是由于其底层技术的差异,它可能对大量项目没有相同的问题。我从来没有想过会有不止一个人需要同时显示超过 10,000 条记录... @Akrem:好吧,如果用户请求了这么多记录并且因此性能不佳,那是他们自己的错。虚拟模式在数据库压力方面无济于事,它只是有助于保持应用对用户的响应更快。 @CodyGray “我对 WPF 真的一无所知,但由于其底层技术的差异,大量项目可能不会出现同样的问题”。实际上,WPF 在这方面存在可怕的性能问题,因为从根本上说,它的渲染管道不支持可见性信息和剔除。我曾经在每个主要的 WPF 应用程序上都遇到过这个性能问题......【参考方案2】:

使用来自ObjectListView 项目的FastObjectListView

50,000 行不算什么,具有自动排序、过滤、按类型查找和其他优点 :)

【讨论】:

【参考方案3】:

不要。如果你想做这样的事情,加载前 500 行和最后 100 行。当用户向下滚动一百行时,自动加载下一批。在 Ctrl+End 上,显示最后 100 个并预加载较早的批次,以防用户向上滚动。

玩弄这些数字,直到您在不实际加载 50K 行的情况下获得让用户感觉流畅的东西

【讨论】:

这当然是虚拟模式允许你实现的。绝对不要通过捕获KeyDown 事件或其他东西来手动执行此操作。这太脆弱了。用户可以通过多种方式滚动控件。而且它也不利于实现搜索功能,这对于这种数量的数据绝对至关重要 @Cody:酷!我不知道虚拟模式。我同意这显然是要走的路。对于搜索功能,我不明白这个问题。不应该在数据库本身而不是在DGV上实现吗?

以上是关于哪个更好用:用于显示大量数据的 DataGrid 或 ListView?的主要内容,如果未能解决你的问题,请参考以下文章

vb哪个列表控件好(listview , datagrid等)

Hbase或hdfs哪个会更好

WPFDataGrid多表头的样式设计

数据集与Sql查询(选择,过程,函数)哪个更好用?

具有大量数据的数据网格使用啥?

开发语言大PK:php和Java哪个更好?