使用大数据填充DatagridView时性能下降

我正在使用BindingSource控件来填充datagridview控件。 它上面有大约1000多条记录。 我正在使用线程来这样做。 在这种情况下,datagridview执行速度非常慢。

我试图将DoubleBuffered属性设置为true,将RowHeadersWidthSizeMode设置为禁用,将AutoSizeColumnsMode设置为none。 但仍然是相同的行为。

请帮助我。 如何提高网格的性能。

提前致谢,
维杰

如果你有大量的行,比如10 000或更多,

避免性能泄漏 – 在数据绑定之前执行以下操作:

dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.EnableResizing; //or even better .DisableResizing. Most time consumption enum is DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders // set it to false if not needed dataGridView1.RowHeadersVisible = false; 

数据绑定后,您可以启用它。

确保你不要自动调整列,它可以提高性能。

即不要这样做Datagridview.Columns [I] .AutoSizeMode = DataGridViewAutoSizeColumnMode.xxxxx;

通常关闭自动resize和双缓冲有助于加速DataGridView填充。 检查DGV双缓冲是否正确打开:

 if (!System.Windows.Forms.SystemInformation.TerminalServerSession) { Type dgvType = dataGridView1.GetType(); PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); pi.SetValue(dataGridView1, value, null); } 

使用WinAPI WM_SETREDRAW消息禁用重绘也有助于:

 // *** API Declarations *** [DllImport("user32.dll")] private static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam); private const int WM_SETREDRAW = 11; // *** DataGridView population *** SendMessage(dataGridView1.Handle, WM_SETREDRAW, false, 0); // Add rows to DGV here SendMessage(dataGridView1.Handle, WM_SETREDRAW, true, 0); dataGridView1.Refresh(); 

如果您不需要双向数据绑定或BindingSource提供的某些function(过滤等),您可以考虑使用DataGridView.Rows.AddRange()方法一次性添加行。

链接到源文章的示例: http : //10tec.com/articles/why-datagridview-slow.aspx

如果您不想覆盖DataGridView所需的虚拟模式方法,则可以考虑使用Listview:

http://www.codeproject.com/Articles/16009/A-Much-Easier-to-Use-ListView

  • 它有一个版本(FastObjectListView),可以在不到0.1秒的时间内构建100,000个对象的列表。
  • 它有一个支持数据绑定的版本(DataListView),另一个支持大型(100,000+)数据集上的数据绑定的FastDataListView。

我知道我已经迟到了,但是我最近厌倦了自动resize对于DataGridView控件的速度有多慢,并且觉得有人可能会从我的解决方案中受益。

我创建了这个扩展方法,用于手动测量和调整DataGridView中的列。 将AutoSizeColumnsMode设置为DataGridViewAutoSizeColumnsMode.None,并在设置DataSource后调用此方法。

 ///  /// Provides very fast and basic column sizing for large data sets. ///  public static void FastAutoSizeColumns(this DataGridView targetGrid) { // Cast out a DataTable from the target grid datasource. // We need to iterate through all the data in the grid and a DataTable supports enumeration. var gridTable = (DataTable)targetGrid.DataSource; // Create a graphics object from the target grid. Used for measuring text size. using (var gfx = targetGrid.CreateGraphics()) { // Iterate through the columns. for (int i = 0; i < gridTable.Columns.Count; i++) { // Leverage Linq enumerator to rapidly collect all the rows into a string array, making sure to exclude null values. string[] colStringCollection = gridTable.AsEnumerable().Where(r => r.Field(i) != null).Select(r => r.Field(i).ToString()).ToArray(); // Sort the string array by string lengths. colStringCollection = colStringCollection.OrderBy((x) => x.Length).ToArray(); // Get the last and longest string in the array. string longestColString = colStringCollection.Last(); // Use the graphics object to measure the string size. var colWidth = gfx.MeasureString(longestColString, targetGrid.Font); // If the calculated width is larger than the column header width, set the new column width. if (colWidth.Width > targetGrid.Columns[i].HeaderCell.Size.Width) { targetGrid.Columns[i].Width = (int)colWidth.Width; } else // Otherwise, set the column width to the header width. { targetGrid.Columns[i].Width = targetGrid.Columns[i].HeaderCell.Size.Width; } } } } 

虽然我当然不会建议使用1000多行填充DGV,但这种方法可以产生巨大的性能优势,同时产生与AutoResizeColumns方法非常相似的结果。

对于10k行:(10K行* 12列。)

AutoResizeColumns = ~3000毫秒

FastAutoSizeColumns = ~140 ms

当用户加载10000个项目或对它们进行排序时,我遇到了性能问题。 当我评论一行时:

 this.dataEvents.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells; 

一切都很顺利。

我认为您需要考虑在虚拟模式下使用数据网格。 基本上,您可以预先设置网格的范围,然后根据需要覆盖“OnCellValueNeeded”。

您应该找到(特别是只有1000行左右)您的网格数量实际上是即时的。

祝好运,