c#填充数据视图的速度非常慢
本文关键字:速度 非常 视图 填充 数据 | 更新日期: 2023-09-27 18:13:46
我正在从一个数据表填充一个datagridview
在填充列和行时,我也同时格式化它,这会导致datagridview加载非常缓慢,是否有解决这个问题的方法?
在处理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列,这部分代码显著提高了速度。