在datagridview中添加新行后,立即显示它

时间:2017-06-23 13:32:39

标签: c# sql winforms performance datagridview

我有一个datagridview。当我以编程方式添加新行时,它应该立即显示在datagridview上,而不是等待完成我拥有的所有行。

我正在使用下面的解决方案

...
adapter.Fill(ds);
foreach (DataColumn dc in ds.Tables[0].Columns)
{
    datagridView1.Columns.Add(dc.ColumnName, dc.ColumnName);
}
foreach (DataRow row in ds.Tables[0].Rows)
{
    datagridView1.Rows.Add(row.ItemArray);
}
...

在这个解决方案上,我必须等到ds.Tables[0].Rows完成,然后datagridview显示这些行。

我要求提供解决方案或建议,我可以看到在datagridview上插入实时行,类似于执行查询后SQL Server上的结果。

2 个答案:

答案 0 :(得分:2)

没有立即添加行的原因是UI线程忙于执行循环,在循环尚未完成时它没有机会重新绘制UI。

解决方案:

  1. 旧的Application.DoEvents()“魔法”召唤。
  2. < =有很多人说Application.DoEvents是邪恶的,我可以为此投票。

    早在.NET的早期,我就被这个神奇的召唤给我留下了深刻的印象。此调用暂停正在进行的任务(添加行),并执行待处理的UI内容,如重新绘制UI,处理鼠标/键盘事件。因此,UI可以保持响应,否则它将被冻结,直到冗长的任务完成。

    所以代码看起来像这样 - 当然,每行调用一次将是性能灾难,如评论中所述。

    foreach (DataRow row in ds.Tables[0].Rows)
    {
        datagridView1.Rows.Add(row.ItemArray);
        Application.DoEvents(); 
    }
    
    1. 使用接受委托的BeginInvoke
    2. BeginInvoke与直接在UI线程上执行循环BeginInvoke之间的差异是异步的。以下是an article解释BeginInvoke。 (哇,我没想到自从.NET 2.0以来就已经可以使用它了,就像一个世纪前一样)。

      Here is an example of adding rows to DataGridView using BeginInvoke

答案 1 :(得分:0)

或者只是使用Databind?

private DataTable Dt = new DataTable();
dataGridView1.DataSource = Dt;
//do what ever
DataRow dataRow = Dt.NewRow();
//add data here to data row
Dt.Rows.Add(dataRow);

虽然这不会解决您的GUI锁定问题,  我建议阅读this