我正在使用DataTable填充DataGridView。
在填充列和行的同时,我还进行了格式化操作,这导致DataGridView加载非常缓慢,是否有解决此问题的方法?
我正在使用DataTable填充DataGridView。
在填充列和行的同时,我还进行了格式化操作,这导致DataGridView加载非常缓慢,是否有解决此问题的方法?
除了处理AutoSizeColumnsMode
外,还要确保各个列的AutoSizeMode
属性也被设置为除了所有单元格之外的其他选项。
我还发现需要使用
SendMessage(dg.Handle, WM_SETREDRAW, false, 0); // before
// updates to datagridview here...
SendMessage(dg.Handle, WM_SETREDRAW, true, 0); // after
使用它后,DataGridView将像Java JTable一样快速 :)
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;
}
对我来说,问题在于ColumnHeadersHeightSizeMode属性,所以我建议使用以下代码片段,其中包含其他回答者提出的一些建议。这样做的优点是,如果您的网格没有以某种方式自动调整大小,则不会盲目地恢复到AutoSize:
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,导入 3 列 10000 行的测试数据,并在数据网格视图中显示每个成功数据的时间从 8 秒缩短到了 3 秒。
微软提供的其他建议包括: DataGridView 优化。
另一种完全不同的方法是使用虚拟化。打开 VirtualMode = true。但这可能需要重构绑定数据事件。请参见: DataGridView 虚拟化。
我遇到了同样的问题,在我的情况下,我还需要设置
DataGridView.RowHeadersWidthSizeMode = DisableResizing
我在一个程序中进行了一些测试,其中我加载了5000行6列的数据,每个单元格都加载了行号以获得一些数据。然后我使用了Stopwatch来测试每种方法。我加载了dataviewgrid,禁用它并加载它,然后启用它,隐藏它,加载它,显示它,以及suspendlayout和resumelayout。我发现,在我的测试中,隐藏它,然后加载它,再显示它要快得多。它花费了: 仅加载需要0.91秒 suspendLayout、加载和resumeLayout需要0.91秒 禁用、加载和重新启用网格需要0.25秒 隐藏、加载和显示网格需要0.19秒。
我同意你应该避免加载不需要的内容,但我认为这个测试会有所帮助。
这是我发现有效的方法。我正在构建一个52x15网格,具有自定义单元格着色,并且使用上面的所有建议生成和显示需要10-20秒的时间,但并没有显著提高性能。
现在这个更改使它在大约1秒内显示,同时使用了双缓冲技术。
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
然后在生成数据完成之后
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;