哪个更好用:用于显示大量数据的 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 可以在虚拟模式下进行搜索。如果不处理此事件,FindItemWithText
和FindNearestItem
方法将返回 null。您可以处理
CacheVirtualItems
event 以维护ListViewItem
对象的缓存。如果创建ListViewItem
对象的计算或查找成本很高,则维护缓存可以提高性能。如果
View
property设置为Tile,当VirtualMode
设置为true时,该值将自动更改为LargeIcon。在虚拟模式下,
Items
集合被禁用。尝试访问它会导致InvalidOperationException
。CheckedItems
集合和SelectedItems
集合也是如此。如果要检索选定或选中的项目,请改用SelectedIndices
和CheckedIndices
集合。
【讨论】:
我对此解决方案进行了一些研究,发现 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?的主要内容,如果未能解决你的问题,请参考以下文章