1

好的,所以我在后台线程中将 DataGridView 绑定到 BindingSource,而“请稍候”模型窗口让用户感到愉悦。没问题。

但是,我需要根据行的 databounditem 类型更改一些行的背景颜色。像这样:

for (int i = 0; i < dgItemMaster.Rows.Count; i++)
{
  if (dgItemMaster.Rows[i].DataBoundItem.GetType().Name == "Package")
  {
   dgItemMaster.Rows[i].DefaultCellStyle.BackColor = Color.PowderBlue;                    
  }
}

以编程方式我可以做到这一点,但它有足够的行,它会在迭代行时锁定 GUI。我正在寻找处理这种情况的最佳方法的想法。

这就是我现在正在做的事情:

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            dgItemMaster.DataSource = products;
            dgItemMaster.BeginInvoke((Action)(() =>
            {
                for (int i = 0; i < dgItemMaster.Rows.Count; i++)
                {
                    if (dgItemMaster.Rows[i].DataBoundItem.GetType().Name == "Package")
                    {
                        dgItemMaster.Rows[i].DefaultCellStyle.BackColor = Color.PowderBlue;
                    }
                    else if (dgItemMaster.Rows[i].DataBoundItem.GetType().Name == "PackageKit")
                    {
                        dgItemMaster.Rows[i].DefaultCellStyle.BackColor = Color.Pink;
                    }
                }
            }));
        }
4

2 回答 2

1

我会尝试运行更改 RowAdded 事件中的背景颜色的代码,这将在每一行添加到网格时触发,无需再次遍历整个列表。

http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.rowsadded.aspx

祝你好运。

于 2008-11-03T21:12:07.877 回答
1

这里的数据量是多少?要让它挂起 UI,它必须是非常重要的。一个极端的答案是切换到虚拟模式——但这是很多工作。

如果您只是不想挂起 UI,也许只需立即执行前x (20?50?) 行,然后分批执行其余的 - 本质上是 emulating ,只是没有...DoEvents的代码气味DoEvents

(未经测试)

        int startIndex = 0;
        Action action = null;
        action = () =>
        {   // only processes a batch of 50 rows, then calls BeginInvoke
            // to schedule the next batch
            int endIndex = startIndex + 50;
            if (endIndex > dgItemMaster.Rows.Count) endIndex = dgItemMaster.Rows.Count;

            if (startIndex > endIndex)
            {
                for (int i = startIndex; i < endIndex; i++)
                {
                    // process row i
                }

                startIndex = endIndex;
                this.BeginInvoke(action); // next iteration
            }                
        };

        // kick it off
        this.BeginInvoke(action);
于 2008-11-04T05:04:29.627 回答