web-dev-qa-db-ja.com

C#ラベルテキストが更新されない

私は次のコードを持っています:

private void button1_Click(object sender, EventArgs e)
{
  var answer =
    MessageBox.Show(
      "Do you wish to submit checked items to the ACH bank? \r\n\r\nOnly the items that are checked and have the status 'Entered' will be submitted.",
      "Submit",
      MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question,
      MessageBoxDefaultButton.Button1);

  if (answer != DialogResult.Yes)
    return;

  button1.Enabled = false;
  progressBar1.Maximum = dataGridView1.Rows.Count;
  progressBar1.Minimum = 0;
  progressBar1.Value = 0;
  progressBar1.Step = 1;

  foreach (DataGridViewRow row in dataGridView1.Rows)
  {
    if ((string) row.Cells["Status"].Value == "Entered")
    {
      progressBar1.PerformStep();

      label_Message.Text = @"Sending " + row.Cells["Name"].Value + @" for $" + row.Cells["CheckAmount"].Value + @" to the bank.";
      Thread.Sleep(2000);
    }
  }
  label_Message.Text = @"Complete.";
  button1.Enabled = true;
}

これは、アプリケーションに移植するために作成しているテストです。すべて正常に機能しますが、label_Message.textが設定されています。画面に表示されることはありません。設定中です。確認のためにconsole.writeを実行しました。画面を更新するだけではありません。最後にも「コンプリート」が出ます。

誰かアイデアはありますか?

12
ErocM

UIスレッドで長い操作を実行しています。 UIスレッドが必要に応じて画面を再描画できるように、バックグラウンドスレッドに移動する必要があります(たとえば、BackgroundWorkerを介して)。不正行為をして実行することができますApplication.DoEvents、しかし私はそれに対して本当にお勧めします。

この質問と回答は基本的にあなたが求めているものです:
C#で他の操作が実行されたときにフォームが応答しない

21
Adam Sills

label.Refresh();を使用します。それは多くの時間を節約します。これはあなたのために働くはずです

17
user3389579

UIスレッドをメッセージループに戻すまで、ラベルは再ペイントされません。 Label.Refreshを試してみてください。または、他のポスターが示唆しているように、長い操作をバックグラウンドスレッドに入れてみてください。

2
Jollymorphic

この操作はUIスレッドで実行されます。 UIは、完了するまで更新されません。送信中に更新するには、別のスレッドで送信を実行し、そこからラベルを更新する必要があります

1
MadBender

これは通常、ユーザーインターフェイス要素が実行されているのと同じスレッドで集中的な計算/反復を実行しているときに発生します。これを回避するには、別のスレッドに作業を行わせ、そこからラベルの値を適宜更新する必要があります。完全なソースサンプルを投稿しますが、現時点では開発マシンから離れています。

0
enriquein