2008-11-03 2 views
1

Итак, я привязываю DataGridView к BindingSource в фоновом потоке, в то время как небольшое окно «Please Wait» хранит пользователя. Нет проблем.Изменение свойств DataGridViewRow в другом потоке

Однако мне нужно изменить некоторые цвета фона строк, основываясь на типе базы данных строки. Как это:

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

Programatically я могу это сделать, но это достаточно строк, что он будет запирать 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; 
        } 
       } 
      })); 
     } 
+0

ОК, это гораздо яснее с этой дополнительной информации. – Alan 2008-11-03 20:48:07

ответ

1

Какой объём данных? Чтобы он повесил интерфейс, он должен быть нетривиальным. Один крайний ответ - переключиться на virtual mode - но это очень много работы.

Если вы просто не хотите, чтобы повесить UI, возможно, просто сделать первые х (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);