【发布时间】:2011-01-02 12:16:25
【问题描述】:
我有一个 SQL 表,目前包含 100 万行,并且会随着时间的推移而增长。
有一个特定的用户要求来呈现一个可排序的网格,该网格显示所有行而不分页。用户希望能够通过使用滚动条非常快速地从一行跳到另一行和从上到下。
我熟悉仅显示整体数据的可见子集的“虚拟模式”网格。它们可以提供出色的 UI 性能和最小的内存需求,(我什至在多年前使用这种技术实现了一个应用程序)。
Windows 窗体 DataGridView 提供了一种看起来应该是答案的虚拟模式。然而,与我遇到的其他虚拟模式不同,它仍然为每一行分配内存(在 ProcessExplorer 中确认)。显然,这会导致总体内存使用量不必要地大大增加,并且在分配这些行时,会出现明显的延迟。滚动性能在超过 100 万行时也会受到影响。
真正的虚拟模式不需要为不显示的行分配任何内存。您只需给它总行数(例如 1,000,000),网格所做的就是相应地缩放滚动条。首次显示时,网格仅要求前 n(例如 30)行可见的数据,即刻显示。
当用户滚动网格时,会提供一个简单的行偏移量和可见行数,可用于从数据存储中检索数据。
这是我当前使用的 DataGridView 代码示例:
public void AddVirtualRows(int rowCount)
{
dataGridList.ColumnCount = 4;
dataGridList.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dataGridList.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
dataGridList.VirtualMode = true;
dataGridList.RowCount = rowCount;
dataGridList.CellValueNeeded += new DataGridViewCellValueEventHandler(dataGridList_CellValueNeeded);
}
void dataGridList_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
e.Value = e.RowIndex;
}
我在这里遗漏了什么,还是 DataGridView 的“虚拟”模式根本不是真正的虚拟?
[更新]
看起来不错的旧 ListView 完全实现了我正在寻找的那种虚拟模式。但是很遗憾ListView没有DataGridView的单元格格式化能力,所以不能用。
对于可能能够做到的其他人,我使用四列 ListView(在详细模式下)、VirtualMode= True 和 VirtualListSize =100,000,000 行对其进行了测试。
列表立即显示,前 30 行可见。然后我可以毫不拖延地快速滚动到列表底部。内存使用量始终为 10 MB。
【问题讨论】:
标签: c# winforms datagridview