DataGridView数据绑定慢的问题

DataGridView数据绑定慢的问题

  • DataGridView数据绑定慢的问题
    • 分页方法
    • 高效使用自动调整大小

DataGridView数据绑定慢的问题

DataGridView数据绑定慢的问题,关注中…

最近为了解决用DataGridView显示大数据(两千多条,近三十几秒,无反应,WinForm程序)时速度很慢的问题,查找了一些资料,记录一下。

上网查了查,发现也有一些网友遇到了这个问题,但许多回答的人并不清楚这个问题的现象和原因,只是想当然地认为大数据绑定就一定会慢,而给出了只适用于Web设计时使用的存储分页方法
尝试了分页方法,发现解决不了慢的问题。

分页方法

//分页方法:
//(1)设置数据加载为模拟模式,this.dataGridView1.VirtualMode = true;
//(2)然后通过CellValueNeeded事件加载数据,这是不能直接用DataSource绑定dataTable1
//直接行数设置,数量相隔很大的话,会很慢,也会导致界面无反应
//  this.dataGridView1.RowCount = retriever.RowCount;
//好像每次改变RowCount的值会自动调用CellValueNeeded事件,
//然后CellValueNeeded事件不只是加载显示的数据,会加载所有行的数据,导致慢
protected override void OnLoad(EventArgs e)
    {
        // Initialize the form.
        this.AutoSize = true;
        this.Controls.Add(this.dataGridView1);
        this.Text = "DataGridView virtual-mode just-in-time demo";

        // Complete the initialization of the DataGridView.
        this.dataGridView1.Size = new Size(800, 250);
        this.dataGridView1.Dock = DockStyle.Fill;
        this.dataGridView1.VirtualMode = true;
        this.dataGridView1.ReadOnly = true;
        this.dataGridView1.AllowUserToAddRows = false;
        this.dataGridView1.AllowUserToOrderColumns = false;
        this.dataGridView1.SelectionMode =
            DataGridViewSelectionMode.FullRowSelect;
        this.dataGridView1.CellValueNeeded += new
            DataGridViewCellValueEventHandler(dataGridView1_CellValueNeeded);

        // Create a DataRetriever and use it to create a Cache object
        // and to initialize the DataGridView columns and rows.
        try
        {
            foreach (DataColumn column in dataTable1.Columns)
            {
                dataGridView1.Columns.Add(
                    column.ColumnName, column.ColumnName);
            }
            this.dataGridView1.RowCount = retriever.RowCount;
        }
        catch (SqlException)
        {
            MessageBox.Show("Connection could not be established. " +
                "Verify that the connection string is valid.");
            Application.Exit();
        }
private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
    {
        e.Value = dataTable1.Rows[e.RowIndex][e.ColumnIndex];
    }

高效使用自动调整大小

我对DataGrid的了解甚少,查到别人将数据集生成并绑定到DataGrid控件上,然后在程序执行时使用Fill填充数据,速度很快(同样的2万条数据)。而现在这个程序是在运行中动态生成数据集然后绑定到DataGridView中,所以我以为是绑定过程消耗了时间。于是又提前生成数据集并绑定到DataGridView上。程序运行后发现时间并没有变快,可以证明速度的快慢与是否提前绑定数据集没有多大关系。而且在绑定完成并显示数据后,如果点击某一列进行排序的话,也需要等十几秒才能排好,这时数据已经绑定,出现这个问题更不应该是绑定的事了。这时想到以前的程序使用的都是DataGrid控件而不是现在的DataGridView控件,于是改用DataGrid控件试了一下,发现这次数据绑定仅等了不到3秒就完成了,显示的数据在排序时速度也非常快,不超过1秒就能完成排序。

由此可以断定是新的DataGridView控件本身造成了速度慢的问题。当然也可能是使用方法不对造成了这个问题。

经过研究,最终发现了DataGridView数据绑定慢的原因,原来是将DataGridView的AutoSizeColumnsMode属性设置为了AllCells,这样就会自动调整数据列的大小。非常喜欢这个功能,但一直没注意到它的响应速度。因为在数据绑定时,开启了 AutoSizecolumnsMode后DataGirdView会对所有数据进行遍历以决定每一列的宽度,所以绑定速度会受到极大的影响,将其改为 DisplayedCells /None即可。

RowHeadersWidthSizeMode属性和ColumnHeadersHeightSizeMode属性,非常影响DataGridView的显示性能,DataGridView的数据绑定应该是迭代的,如果你把DataGridViewRowHeadersWidthSizeMode设置了AuToSize类型的属性,那么每设置一行就要进行一次对HeaderWidth的调整,那么对于N行的表就将进行N!次操作,再加上列的情况,这种性能损失将是巨大的.

dgvData_Signal.RowCount = dtSignal.Rows.Count;

//在Designer.cs 代码中设置
//If you have a huge amount of rows, like 10,000 and more, to avoid performance leaks - do the following before data binding:

dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.EnableResizing;
// or even better, use .DisableResizing. Most time consuming enum is DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders
// set it to false if not needed
dataGridView1.RowHeadersVisible = false;
//After the data is bound, you may re-enable it.

刷新前Clear:

dgvData_Signal.Rows.Clear();
dgvData_Signal.RowCount = dtSignal.Rows.Count;

链接: 参考微软官网的样例.
链接: Winform DataGridView VirtualMode 设置RowCount 很慢.

你可能感兴趣的:(开发语言,c#)