我有一个包含100万行数据的SQL表,未来还会增长。
用户要求以可排序的方式显示所有行,不分页。用户期望使用滚动条可以快速跳转到任意行和顶部底部。
我熟悉“虚拟模式”网格,它只显示整个数据的一个可见子集。 它们提供出色的UI性能和最小的内存需求(我甚至在多年前实现了一个应用程序使用这种技术)。
Windows Forms 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行可见。然后我可以快速滚动到列表底部而没有延迟。内存使用量始终保持在10MB。