显示大型数据表
Posted
技术标签:
【中文标题】显示大型数据表【英文标题】:Displaying a large table of data 【发布时间】:2017-01-17 03:38:54 【问题描述】:免责声明:我的职业生涯一直是嵌入式软件,而我最近才涉足桌面应用程序。我正在开发的应用程序有一个模拟,它产生一个稀疏的二维矩阵,可以是 3000x3000 个元素的数量级。稀疏矩阵对象来自我们在内部创建的一个类。我需要以扩展形式向用户显示这个稀疏矩阵。
我最初将其扩展为 DataTable 并将其绑定到 DataGridView,但由于列 FillWeights 的总和超过限制而遇到障碍。即使克服了这一点,在表格中显示任何内容之前也需要几分钟的处理时间。
我遇到了 DataGridView 的虚拟模式。虚拟模式似乎非常适合我所拥有的,但仍然存在几个问题:
-
似乎没有办法向 DataGridView 传达最大行数和/或列数(用于缩放滚动条)。如果我设置 .RowCount 和/或 .ColumnCount,应用程序会挂起 2 分钟以创建列。
我在虚拟模式下失去了列排序。在 MSDN 文档中似乎有一些方法可以做到这一点,但并不明显。
这让我相信 GUI 世界中的数据不适合在笨重的大表(特别是有数千列)中查看,尤其是考虑到我们已经以稀疏矩阵形式获得它。我想我需要推迟这个要求。
在我的情况下你会怎么做?
【问题讨论】:
我会首先确定为什么需要这么长时间。如果您正在查询数据库,则时间不是来自于在 DGV 中显示数据,而是来自于从数据库中获取数据的时间。我使用 DGV 从数据库中显示近 1,000,000 行,但从数据库中提取数据确实需要时间。您是说问题是时间,然后将问题归咎于显示器。请下定决心,真正的问题是什么!!! 正如我在最初的文章中所说,数据位于本地内存中的本地数据结构中。无需考虑网络或数据库延迟。将 .RowCount 和 .ColumnCount 计数设置为 3000 的简单操作需要几分钟的处理才能显示任何内容。我会收紧 OP 中的语言,以免混淆。 您应该编写自己的 DataGrid 或寻找第三方来显示大量 列。 【参考方案1】:如果有任何列的 AutoSizeMode 设置为 None 以外的值,则设置 RowCount 可能需要很长时间。如果您需要其他设置,可以暂时将它们设置为 none,然后设置 RowCount,然后将它们设置为您真正想要的。
至于列排序,你必须自己动手,但我发现这比预期的要容易。您需要几个字段来记录当前排序的列(索引)以及方向:
private int _currentSortedColumnIndex = -1; // No sorting at first
private SortOrder _sortOrder = SortOrder.None;
那么你需要为ColumnHeaderMouseClick设置一个事件处理函数:
myDataGridView.ColumnHeaderMouseClick += MyDataGridView_ColumnHeaderMouseClick;
事件处理程序本身将排好序的列配置为具有正确的排序字形,并触发对源数据的排序:
private void MyDataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
if (_currentSortedColumnIndex >= 0 && _currentSortedColumnIndex < myDataGridView.ColumnCount)
mysDataGridView.Columns[_currentSortedColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.None;
if (_currentSortedColumnIndex == e.ColumnIndex)
_sortOrder = _sortOrder == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
else
_currentSortedColumnIndex = e.ColumnIndex;
_sortOrder = SortOrder.Ascending;
mysDataGridView.Columns[_currentSortedColumnIndex].HeaderCell.SortGlyphDirection = _sortOrder;
SortRecords(_currentSortedColumnIndex, _sortOrder);
RefreshGrid();
SortRecords() 是您准备数据缓存的地方,以便 CellValueNeeded 事件处理程序可以按新的排序顺序提供单元格,该排序顺序存储在 _currentSortedColumnIndex 和 _sortOrder 中。
RefreshGrid() 是您基本上清除网格的地方,以便它开始触发 CellValueNeeded 事件。
【讨论】:
以上是关于显示大型数据表的主要内容,如果未能解决你的问题,请参考以下文章