【问题标题】:After adding a new row in datagridview, display it immediately在datagridview中添加新行后,立即显示
【发布时间】:2023-04-02 04:19:01
【问题描述】:

我有一个数据网格视图。当我以编程方式添加新行时,它应该立即出现在 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 上的结果类似。

【问题讨论】:

  • 您知道这会减慢所有记录的呈现速度吗?如果您想分块加载,那很好,但是在每一行之后都是矫枉过正的。作为记录,几年前我有一个 DataGridView,我将 30k 条记录加载到(大约 20 列)中,耗时不到一分钟。如果我再次从事那个项目,我会将其分解为最有可能一次 1k,然后继续加载,直到我拥有一切。

标签: c# sql winforms performance datagridview


【解决方案1】:

还是只使用 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

【讨论】:

    【解决方案2】:

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

    解决方案:

    1. 旧的Application.DoEvents()“魔法”电话。

    Application.DoEvents 是邪恶的,我可以为此投反对票。

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

    所以代码看起来像这样 - 当然,如 cmets 中所述,为每一行调用一次会导致性能灾难。

    foreach (DataRow row in ds.Tables[0].Rows)
    {
        datagridView1.Rows.Add(row.ItemArray);
        Application.DoEvents(); 
    }
    
    1. 使用BeginInvoke,它接受委托。

    BeginInvoke和直接在UI线程上执行循环的区别在于BeginInvoke是异步的。这是an article 解释BeginInvoke。 (哇,我没想到它从 .NET 2.0 开始就可以使用,就像一个世纪前一样)。

    Here is an example of adding rows to DataGridView using BeginInvoke.

    【讨论】:

    • 这修复了在向 DatagridView 添加行后立即选择新行的问题。 ArgumentOutOfBoundException 由于没有立即创建行。并选择它给你。
    猜你喜欢
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 2014-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    相关资源
    最近更新 更多