使用大数据填充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
虽然我当然不会建议使用1000多行填充DGV,但这种方法可以产生巨大的性能优势,同时产生与AutoResizeColumns方法非常相似的结果。
对于10k行:(10K行* 12列。)
AutoResizeColumns = ~3000毫秒
FastAutoSizeColumns = ~140 ms
当用户加载10000个项目或对它们进行排序时,我遇到了性能问题。 当我评论一行时:
this.dataEvents.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells;
一切都很顺利。
我认为您需要考虑在虚拟模式下使用数据网格。 基本上,您可以预先设置网格的范围,然后根据需要覆盖“OnCellValueNeeded”。
您应该找到(特别是只有1000行左右)您的网格数量实际上是即时的。
祝好运,