用户界面-线程期间更新UI(Windows窗体,C#)
本文关键字:窗体 Windows UI 线程 更新 用户界面 | 更新日期: 2023-09-27 17:57:47
我已经为这个问题挣扎了一段时间,我似乎不是唯一一个。关于这个话题有很多线索,但似乎没有一个对我有用。希望这里有人能给我指明正确的方向。
总结:我创建了一个带有许多控件的windows窗体。用户可以设置这些控件,然后"启动"测试。这会触发一个线程,这样我仍然可以在测试期间访问windows表单(这可能会持续数周)。我想在这个线程中更新UI,但是,我还没有弄清楚如何做到这一点。
我写了一个非常小的windows窗体应用程序,认为用它来解释我的问题会更容易,然后我可以使用这里给出的建议来解决我的大问题。
这是我的小程序的代码,目前还没有编译
using System;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Thread thread = new Thread(() => startNewThread());
thread.Start();
}
public static void startNewThread()
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
string text = string.Format("Time: [{0}]", i);
label1.Invoke((Action)delegate { label1.Text = text; });
}
}
}
}
我试图使用@JaredPar在这个帖子中给出的建议,但我无法让它为我工作。然而,我的意图是点击按钮,转到帖子,更新帖子中的标签。就像我说的,我还不能编译,并收到以下错误:
An object reference is required for the non-static field, method, or property 'Form1.label1'
任何帮助都将不胜感激,我为我缺乏知识而道歉,因为我认为这是完全基本的。我每天都在学习。
提前感谢
只是为了解决您的问题:
- 线程函数不能是静态的
- 使用这个。调用而不是Label.Invoke
但是,如果您总是希望定期并在一致的时间内更新UI,则更好的解决方案是使用System.Windows.Timer,这是一个在主UI线程上运行的计时器,并按初始化间隔计时。那么您就不必使用Invoke方法了。
看看这里:https://msdn.microsoft.com/en-us/library/system.windows.forms.timer(v=vs.110).aspx
处理UI线程可能很棘手。这是一个对我来说很方便的技巧。将以下扩展方法添加到您的项目中。
public static class WindowsFormsControlExtensions
{
public static void Invoke(this Control control, Action action)
{
control.Invoke(action);
}
}
在表单类中添加方法时,可以使用扩展,如下所示。this
关键字将引用表单,并且包含的代码将在包含表单句柄的线程上执行。
public void SetLabel(string text)
{
this.Invoke(() =>
{
if (label1 != null)
label1.Text = text;
});
}