显示大型数据表

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 事件。

【讨论】:

以上是关于显示大型数据表的主要内容,如果未能解决你的问题,请参考以下文章

在网站上显示大型 Excel 文件中的数据的最佳方式

php html 在一个电视仪表板中显示大型动态表格数据

如何将显示的 sql 数据加载到 wpf 可滚动列表视图中?大型集合(20k+)而不会遇到内存问题?

使用 django 处理大型 jquery 数据表很慢

将大型数据集绑定到 JQuery 控件

如何高效地按小时查询大型数据库?