我有以下代码:
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来验证。它只是没有刷新屏幕。我也在最后获得了“完整”。
有人有什么想法吗?
答案 0 :(得分:21)
您正在UI线程上执行冗长的操作。您应该将其移动到后台线程(例如,通过BackgroundWorker
),以便UI线程可以在需要时执行重绘屏幕等操作。你可以欺骗并执行Application.DoEvents
,但我真的建议反对它。
这个问题和答案基本上就是你所要求的:
Form Not Responding when any other operation performed in C#
答案 1 :(得分:17)
使用Label.Refresh();它节省了很多时间。这应该适用于你
答案 2 :(得分:2)
在将UI线程返回到消息循环之前,Label不会重新绘制。尝试Label.Refresh,或者更好的是,尝试将其冗长的操作放在后台线程中,就像其他海报所建议的那样。
答案 3 :(得分:1)
此操作在UI线程中执行。 UI完成后才会更新。要在发送期间进行更新,您必须在单独的线程中执行发送并从那里更新标签
答案 4 :(得分:0)
当您在与运行用户界面元素相同的线程中进行密集计算/迭代时,通常会发生这种情况。要解决这个问题,你需要有一个单独的线程来完成工作,并从那里相应地更新标签的值。我发布了一个完整的源代码示例,但此刻我离开了我的开发机器。
答案 5 :(得分:0)
仅添加到此答案,我的启动画面表单出现了问题。 我们有这样的代码:
SplashScreen.Initialize(this, SplashScreenImage);
SplashScreen.Show();
// Db init, log init etc.
... Further in our app ...
Application.Run(new MainWindowForm());
在Initialize(this, SplashScreenImage);
中,我们更新了一些控件,然后刷新了这些控件;
public void Initialize(this, SplashScreenImage)
{
...
lblVersion.Text = GetVersionString();
lblEnv.Text = GetEnvironmentString();
// Refresh (does not work)
lblVersion.Refresh()
lblEnv.Refresh()
}
不幸的是,这不起作用。这里的问题是,尽管我们显式调用了control.Refresh()
,但是在调用form.show()
之后又调用了control.refresh
。这不起作用。
修复很简单:
SplashScreen.Show(); // First call show
SplashScreen.Initialize(this, SplashScreenImage); // Now contorl.Refresh() works
答案 6 :(得分:0)
我知道这个问题很旧,但是我也遇到了同样的问题。我尝试了Refresh()和其他很多方法,但是没有任何效果。如果我将文本放到Messagebox.show中,则它可以在消息框中工作,但不能在表单中工作,所以我知道我有数据。当我有很多人在等待使用该应用程序时,我感到绝望了,当我想尝试使用Invoke时,正要暂时取消该类,以使其正常运行。所以我尝试了
Invoke(new Action(() =>
{
lbltxt.Text = text;
}));
目前它可以工作,但仍然不确定这是长期修复还是仅仅是石膏,直到我找到更好的解决方案为止。