C# 如何在秒后更改标签文本?

C# 如何在秒后更改标签文本?,c#,winforms,C#,Winforms,我已经寻找并尝试了许多解决这个问题的方法。 使用Visual Studio 2015 WinForma应用程序,我希望在延迟一段时间后更改标签的文本。 在我的许多方法中,我可以用消息框确认标签的字符串值已更改,但屏幕UI没有更改。 到目前为止,我一直在尝试: 1:Thread.Sleep(number)insidePublic Form1()在我更改值之前。 结果:在函数结束之前似乎没有更新UI。 2:nameoflabel.refresh()无处不在。 结果:在任何地方都不做任何事情。 3:使

我已经寻找并尝试了许多解决这个问题的方法。

使用Visual Studio 2015 WinForma应用程序,我希望在延迟一段时间后更改
标签的文本。

在我的许多方法中,我可以用
消息框
确认标签的字符串值已更改,但屏幕UI没有更改。

到目前为止,我一直在尝试:

1:
Thread.Sleep(number)
inside
Public Form1()
在我更改值之前。
结果:在函数结束之前似乎没有更新UI。

2:
nameoflabel.refresh()无处不在。
结果:在任何地方都不做任何事情。

3:使用
System.Timers
并在计时器的已用功能内更改my
标签的值。
结果:更改
标签的值,但不在屏幕上显示。

4:由于所有涉及按钮点击的操作都能完美地改变我的标签文本,因此我研究了如何使用
buttonName.preformClick()
模拟按钮点击,并为此制作了一个假按钮。
结果:值更改,但屏幕上仍然没有任何更改。

我开始相信这一定是一个错误。对不 无论如何,我需要做的是:

public partial class Form1 : Form
{
    public System.Timers.Timer holder;
    Label say;

    public Form1()
    {
        InitializeComponent();

        say = new Label();
        say.Text="start text";
        this.Controls.Add(say);
        holder = new System.Timers.Timer(5000);
        holder.Elapsed += new ElapsedEventHandler(holdone); 
        holder.Enabled = true;
    }

    public void holdone(Object source, ElapsedEventArgs e)
    {
        //messagebox is correct but onscreen gui is not
        say.Text = "new after seconds";
        MessageBox.Show(say.Text);
    }
}
这是一个
System.Timers.Timer
事件处理程序的示例,它应该(相对地)立即影响您的UI


这是一个
System.Timers.Timer
事件处理程序的示例,它应该(相对地)立即影响您的UI。

您可以使用
System.Windows.Forms.Timer
,它将根据需要更新UI:

public partial class Form1 : Form
{
    private System.Windows.Forms.Timer holder;
    private System.Windows.Forms.Label say;

    public Form1()
    {
        InitializeComponent();

        say = new Label {AutoSize = true, Text = "start text"};
        Controls.Add(say);

        holder = new Timer {Interval = 5000};
        holder.Tick += HolderTick;
        holder.Enabled = true;
    }

    private void HolderTick(object sender, EventArgs e)
    {
        say.Text = $"new after {holder.Interval / 1000} seconds";
        holder.Enabled = false;
    }
}

您可以改用
系统.Windows.Forms.Timer
,它将根据需要更新UI:

public partial class Form1 : Form
{
    private System.Windows.Forms.Timer holder;
    private System.Windows.Forms.Label say;

    public Form1()
    {
        InitializeComponent();

        say = new Label {AutoSize = true, Text = "start text"};
        Controls.Add(say);

        holder = new Timer {Interval = 5000};
        holder.Tick += HolderTick;
        holder.Enabled = true;
    }

    private void HolderTick(object sender, EventArgs e)
    {
        say.Text = $"new after {holder.Interval / 1000} seconds";
        holder.Enabled = false;
    }
}

使用Timer方法,您应该使用对
main窗口
的目标UI元素的引用,以及
Invoke
方法。由于
appeased
事件是在单独的线程上处理的,因此您必须向UI线程发出信号,要求其不仅更改属性,而且影响属性,当由UI线程以外的任何其他实体插入时,
Invoke
BeginInvoke
(非阻塞异步替代)使用。使用
系统.Windows.Forms.Timer
。它的
勾选
事件在UI线程中引发。到目前为止,您应该会收到一个
invalidoOperationException
,用于尝试跨线程操作。我根据上面的评论添加了一个示例<代码>调用
达到了@Jimi在回答中强调的效果。无论采用哪种技术,UI都必须被取消阻止,并且是影响所需实时更新的属性更改的UI。不允许从工作线程更新控件的文本属性。您会得到一个InvalidOperationException,但System.Timers.Timer是一个非常讨厌的类,它会吞噬在已用事件处理程序中引发的所有异常。使用工具箱中的普通计时器。使用计时器方法,您应该使用对
主窗口
的目标UI元素的引用,以及
调用
方法。由于
appeased
事件是在单独的线程上处理的,因此您必须向UI线程发出信号,要求其不仅更改属性,而且影响属性,当由UI线程以外的任何其他实体插入时,
Invoke
BeginInvoke
(非阻塞异步替代)使用。使用
系统.Windows.Forms.Timer
。它的
勾选
事件在UI线程中引发。到目前为止,您应该会收到一个
invalidoOperationException
,用于尝试跨线程操作。我根据上面的评论添加了一个示例<代码>调用
达到了@Jimi在回答中强调的效果。无论采用哪种技术,UI都必须被取消阻止,并且是影响所需实时更新的属性更改的UI。不允许从工作线程更新控件的文本属性。您会得到一个InvalidOperationException,但System.Timers.Timer是一个非常讨厌的类,它会吞噬在已用事件处理程序中引发的所有异常。使用一个普通的计时器,工具箱中的计时器。谢谢你,你用窗体计时器代替系统计时器的解决方案已经解决了我的问题,我现在使用你的例子!!!谢谢你,你用一个窗体计时器代替系统计时器的解决方案解决了我的问题,我现在用你的例子!!!谢谢,这似乎是一个很好的解决方案。目前,我已经使用了Rufus的第一个答案,但将研究调用和委托在未来编码中的使用。您的方法似乎更具普遍性,可供将来参考。谢谢,这似乎是一个很好的、不可接受的解决方案。目前,我已经使用了Rufus的第一个答案,但将研究调用和委托在未来编码中的使用。你的方法似乎更具普遍性,以备将来参考