【问题标题】:Changing DataGridViewRow Properties in Another Thread在另一个线程中更改 DataGridViewRow 属性
【发布时间】:2008-11-03 20:10:20
【问题描述】:

好的,所以我在后台线程中将 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;
                    }
                }
            }));
        }

【问题讨论】:

  • 好的,有了这些额外的信息,现在更清楚了。
  • 是的,我的错,我应该更清楚。
  • 我能想到的最好的就是 RowsAdded 事件,但我不推荐它,因为我从来没有通过这种基于事件的更新获得 100% 的可靠性。 (另外,我不确定 RowsAdded 在使用数据绑定时是否保证为每个添加的行单独触发。)

标签: c# multithreading datagridview


【解决方案1】:

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

如果您只是不想挂起 UI,也许只需立即执行前 x(20?50?)行,然后分批执行剩余的行 - 基本上模拟 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);

【讨论】:

    【解决方案2】:

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

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

    祝你好运。

    【讨论】:

      猜你喜欢
      • 2014-03-28
      • 1970-01-01
      • 1970-01-01
      • 2020-02-21
      • 2017-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多