我有一个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上的结果。
答案 0 :(得分:2)
没有立即添加行的原因是UI线程忙于执行循环,在循环尚未完成时它没有机会重新绘制UI。
解决方案:
Application.DoEvents()
“魔法”召唤。 < =有很多人说Application.DoEvents
是邪恶的,我可以为此投票。
早在.NET的早期,我就被这个神奇的召唤给我留下了深刻的印象。此调用暂停正在进行的任务(添加行),并执行待处理的UI内容,如重新绘制UI,处理鼠标/键盘事件。因此,UI可以保持响应,否则它将被冻结,直到冗长的任务完成。
所以代码看起来像这样 - 当然,每行调用一次将是性能灾难,如评论中所述。
foreach (DataRow row in ds.Tables[0].Rows)
{
datagridView1.Rows.Add(row.ItemArray);
Application.DoEvents();
}
BeginInvoke
。 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。