我有一个带有状态栏的Windows窗体,显示当前的应用程序状态。 我有一个名为AppState的类,它在状态栏中更新了Label,并且在处理它时将状态更改回“Ready”。
在执行类似操作时的代码中:
using (AppState state = new AppState("Processing..."))
{
//Do some work that take some seconds
}
但标签保持不变。我没有任何例外。标签文本已更新,但在UI上,它会一直显示以前的值。我在这里错过了什么吗?
你是对的,这是我唯一能做的事情。这是AppState代码public class AppState : IDisposable
{
static string Default = "Ready";
public AppState(string status)
{
Form.StatusLabel.Text = status;
}
public void Dispose()
{
Form.StatusLabel.Text = Default;
}
}
答案 0 :(得分:5)
总是一样的......
如果你想开始需要一段时间的事情,不要在你的GUI线程中做,否则你的GUI会冻结(没有标签更新,没有调整大小,没有移动,没有任何东西)。
使用Application.DoEvents()在千个地方填写代码也是一种不好的做法。
如果你有一个长时间运行的任务(长意味着> 1秒)你应该使用BackgroundWorker。也许它在开始时有点难,但如果你的程序变得更复杂,你会喜欢它。由于事实已经多次讨论过,这里有一个link with some sample code。
现在您已经知道正确的工具(BackgroundWorker)来解决您的问题,您应该让它工作(或者询问有关您的新特定问题的其他问题)。
答案 1 :(得分:4)
看起来您想在设置Application.DoEvents()
文本字段值后放置StatusLabel
。这告诉Windows Forms处理表单的Windows事件队列,导致更改重绘。
答案 2 :(得分:2)
为了“线程安全”,请使用调用,并使用以下格式的 InvokeRequired 进行测试:
// code outside the myForm:-----------------------
if (myForm.InvokeRequired)
myForm.Invoke(new ChangeLabelEventHandler(ChangeLabel), "teeeest");
else
myForm.ChangeLabel("teeeest");
// code in the myForm:-----------------------------
public delegate void ChangeLabelEventHandler(string newText);
private void ChangeLabel(string newLabelText)
{
this.label1.Text = newLabelText;
}
答案 3 :(得分:2)
我是C#的新手,但为什么你不能这样做:
private void updateStatusBar(string status)
{
if (StatusLabel.InvokeRequired)
{
StatusLabel.Invoke((MethodInvoker)(() =>
{
StatusLabel.Text = status;
}));
}
else
{
StatusLabel.Text = status;
}
}
如果要更新状态?
答案 4 :(得分:0)
也许多线程可以解决您的问题。
最简单的方法是使用BackgroundWorker。
原因是UI只能在UI线程没有其他任何操作时重绘。并且你用你的计算来阻止它。
答案 5 :(得分:0)
使用Label.Refresh();它节省了很多时间。这应该适用于你