如何在C#中的循环中多次更改控件的属性
本文关键字:属性 控件 循环 | 更新日期: 2023-09-27 18:00:52
我正在尝试这样做:
int i;
while(true)
{
label1.Text = i.ToString();
i++;
Thread.Sleep(500);
}
(事实上,我正试图做一些更复杂的事情,这更有意义,但这是我问题的一个简单例子(我预计标签的文本每1/2秒就会更改一次。。但它被卡住了。
感谢
你不能让GUI线程休眠(因为GUI不会响应((我是说,尽管我喜欢睡觉*很多*(。
考虑以下备选方案之一:
- 在单独的线程上运行此代码
- 创建一个以500为间隔的计时器
- 某种绑定
睡眠UI线程会让变得更糟,因为它在完成方法之前无法响应"绘制"事件。
这里最合适的选择是一个计时器,在每个刻度上做一些工作。
添加Application是一种懒惰且存在严重缺陷的方法。DoEvents((-我提到这一点只是为了让我说不要这么做!!!
使用后台线程或计时器,否则会阻塞UI:
Thread t = new Thread( () =>
{
int i = 0;
while (true)
{
label1.Invoke( new Action(() => { label1.Text = i.ToString();}));
i++;
Thread.Sleep(500);
};
});
t.IsBackground = true;
t.Start();
按照现在的方式,您的代码与GUI在同一个线程上运行。设置新的标签文本后,您将立即进入睡眠状态,这将阻止任何负责实际更新屏幕的代码运行。您可以将Application.DoEvents()
放在睡眠呼叫之前,以强制它处理任何消息,但这不是一个真正的解决方案。
您需要做的是将耗时的代码放到另一个线程上。这个NET Timer类是为类似这样的简单操作而创建的。您还可以制作自己的单独线程,其中包含循环代码。只需确保您只能从创建标签的同一线程访问标签。您可以通过将委托传递给label1.Invoke
来完成实际的文本更新。
循环上没有中断条件
也许你正在尝试这样做,看看Update被调用来重新绘制标签。
int i;
for (i=0; i!=10; i++){
label1.Text = i.ToString();
label1.Update();
Thread.Sleep(500);
}
您永远无法摆脱while循环,从而摆脱卡住的部分。此外,如果这是一个WinForm,您需要重新绘制/使其无效/刷新您的UI以查看任何更新。关于这方面的更多信息:C#:当我的表单';你没有集中注意力吗?