c#填充数据视图的速度非常慢

本文关键字:速度 非常 视图 填充 数据 | 更新日期: 2023-09-27 18:13:46

我正在从一个数据表填充一个datagridview

在填充列和行时,我也同时格式化它,这会导致datagridview加载非常缓慢,是否有解决这个问题的方法?

c#填充数据视图的速度非常慢

在处理AutoSizeColumnsMode的同时,确保各个列的AutoSizeMode属性也设置为除所有单元格之外的其他属性。

我也发现有必要使用

SendMessage(dg.Handle, WM_SETREDRAW, false, 0); // before
// updates to datagridview here...
SendMessage(dg.Handle, WM_SETREDRAW, true, 0); // after

这样就可以像java jtable那样快速地生成datagridview:)

public static class ExtensionMethods
{
    public static void DoubleBuffered(this DataGridView dgv, bool setting)
    {
        Type dgvType = dgv.GetType();
        PropertyInfo pi = dgvType.GetProperty("DoubleBuffered",
            BindingFlags.Instance | BindingFlags.NonPublic);
        pi.SetValue(dgv, setting, null);
    }
}
ExtensionMethods.DoubleBuffered(dataGridView1, true);

加载1-2k行大约需要2-4分钟。我改变了自动调整大小的属性,现在它下降到秒,可能10-20。我在行创建循环之前运行这个程序,以确保它获得所有列。

foreach (DataGridViewColumn c in thisGrid.Columns)
{
    c.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
}

您可以检查DataGridView - autosizecolumnmode的属性我发现,如果我改变模式从AllCells到DisplayedCells的性能是不同的。我希望这对你有帮助。

当您使用数据网格视图来显示数据库中的数据时,您应该始终考虑使用一些策略来限制结果集,并仅在用户真正看到记录时才显示记录。这有时被称为虚拟模式或数据分页。我有一个wpf策略的例子,但也有一些适用于winforms的策略。看看这个问题:与MS Access Grid相比,Winform DataGridview非常慢,我认为这也与你的问题有关。

一个傻老头的规矩:-避免DataTable,众所周知它是低效的-避免使用预分配行["Grid"]。Rowcount +"Grid".AddRange() +..(比"Grid"ADD()慢5倍)-考虑一个DataGridView绑定到"你的屏幕":即。用几屏数据加载它。-我应用了这些简单的事实,我可以在15秒内"加载"一个42万行159列的"愚蠢文件"(~200 MB)。

我在一个程序中做了一些测试,在这个程序中,我加载了5000行6列,每个单元格都加载了行号,只是为了有一些数据。然后我用Stopwatch测试了每种方法。我加载dataviewgrid,禁用它并加载它,然后启用它,隐藏它,加载它并显示它,并暂停布局和恢复布局。在我的测试中,我发现通过隐藏它,加载它,然后显示它,速度要快得多。了:。91秒装弹.91秒来暂停布局,加载,恢复布局25秒内禁用,加载和重新启用电网.19秒隐藏,加载和显示网格

我同意你应该避免加载你不需要的东西,但我认为这个测试会有所帮助。

我也有同样的问题,在我的情况下,我也不得不设置DataGridView.RowHeadersWidthSizeMode = DisableResizing

我发现这是有效的。我正在用自定义单元格着色构建一个52x15的网格,它需要10-20秒来生成和显示,上面的所有建议并没有提高多少性能。

这个更改现在使它在大约1秒内显示,以及上面的双缓冲。

dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;

生成完数据后

dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;

对于我来说,问题是与ColumnHeadersHeightSizeMode属性有关,所以我建议这个代码片段包含了其他受访者的一些建议。这样做的好处是,如果你的网格没有自动调整大小,就不会盲目地恢复到自动调整大小。:

private static void FastLoadDataGrid<T>(DataGridView dgv, IEnumerable<T> objList)
{
    // Cache old values
    DataGridViewAutoSizeColumnsMode oldAutoSizeCols = dgv.AutoSizeColumnsMode;
    DataGridViewAutoSizeRowsMode oldAutoSizeRows = dgv.AutoSizeRowsMode;
    DataGridViewRowHeadersWidthSizeMode oldRowHeader = dgv.RowHeadersWidthSizeMode;
    DataGridViewColumnHeadersHeightSizeMode oldCol = dgv.ColumnHeadersHeightSizeMode;
    dgv.SuspendLayout(); // off for performance 
    // switch off stuff for performance
    dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; 
    dgv.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None; 
    dgv.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
    dgv.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
    // flush and load data source 
    dgv.DataSource = null;
    dgv.DataSource = new List<T>(objList); //wrap in sortable bindinglist to allow user to sort via column header click
    // revert back to old values
    dgv.AutoSizeColumnsMode = oldAutoSizeCols;  
    dgv.AutoSizeRowsMode = oldAutoSizeRows; 
    dgv.RowHeadersWidthSizeMode = oldRowHeader;
    dgv.ColumnHeadersHeightSizeMode = oldCol;
    dgv.ResumeLayout(false); // turn back on
}
对这个过程的典型调用是:
FastLoadDataGrid(MyDataGridView, MyListOfCustomers);

通过使用FastLoadDataGrid,导入10000行3列的测试,每次成功都显示在数据网格视图中,从8秒减少到3秒。

微软的其他建议是:DataGridView优化

另一种完全不同的方法是使用虚拟化。打开VirtualMode = true。但这可能需要重构数据绑定事件。看到的:DataGridView虚拟化

我的DataGridView性能比较好。添加几百行大约需要200ms。我是这样做的:

virtual = true——使用虚拟化数据网格视图似乎使整个过程更快。只要记住正确地实现logViewGrid_CellValueNeeded

另一个要做的事情是在向绑定列表添加数据时暂时禁用布局事件。试着做:

logViewGrid.SuspendLayout();
// add data, perform some operations on grid view
logViewGrid.ResumeLayout(false);

我也有一个问题与慢行着色;我的方法是分别设置每个单元格的样式,像这样:

gridViewInstance.Rows[currentRow].Cells[cellIndex].Style.BackColor = val;

我改成了:

gridViewInstance.Rows[currentRow].DefaultCellStyle.BackColor = val;

对于30列,这部分代码显著提高了速度。