0

I'm trying to get a simple label value to change from another thread, and already tried 3 different threading mechanisms (Tasks, Thread, Background worker) and am now at a loss why the control won't update.

I have a method in an unrelated class like this:

 public static void SetOverlayText(string text, bool fade = false)
      {
         Thread myThread = new Thread(FadeOverlayText);
         OverlayForm.SetLabelText(text);

         if (fade)
         {
            myThread.Start();
         }
      }

and

private static void FadeOverlayText()
      {
        OverlayForm.ClearLabelText();
      }

My form is a regular windows form and has that method:

public void ClearLabelText()
      {
         this.Invoke((MethodInvoker)delegate
         {
            StatusText.Text = "Something should happen"
            StatusText.Refresh();
         });

      }

The method appears to be getting called, but nothing happens.

JL.
  • 78,954
  • 126
  • 311
  • 459
  • 1
    possible duplicate of [How to update the GUI from another thread in C#?](http://stackoverflow.com/questions/661561/how-to-update-the-gui-from-another-thread-in-c) – DotNetRussell Jan 27 '15 at 12:26
  • Before you guys close this adding a coded ui tag. – JL. Jan 28 '15 at 17:02

2 Answers2

0

You should not need Refresh.

This should work:

public void ClearLabelText()
{
    if (StatusText.InvokeRequired)
    {
         this.Invoke((MethodInvoker)delegate
         {
            StatusText.Text = "Something should happen";
         });
    }
    else
    {
      StatusText.Text = "Something should happen";
    }
}

Are you shure, you use the correct control and at no other point the string is changed, so that it seems not to work? Please check every thing.

Also be sure, that you only call ClearLabelText once in your second thread, becuase after ClearLabelText is finished, the thread is not alive anymore.

This will update your text every second, as long as the application runs:

private static void FadeOverlayText()
{
    var uiThread = <<Your UI Thread>>;

     while(uiThread.IsAlive)
    {
        OverlayForm.ClearLabelText();

        Thread.Sleep(1000);
    }
}

EDIT:

here is a simple example i've made and it works. Additionaly to your StatusText label, I've added button1, which change the text too.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace ThreadTest2
{
    public partial class Form1 : Form
    {
        Thread mainThread = null;

        public Form1()
        {
            InitializeComponent();

            mainThread = Thread.CurrentThread;

            Thread myThread = new Thread(FadeOverlayText);
            myThread.Start();
        }


        private void FadeOverlayText()
        {

            while (mainThread.IsAlive)
            {
                ClearLabelText();

                Thread.Sleep(1000);
            }
        }

        public void ClearLabelText()
        {
            if (StatusText.InvokeRequired)
            {
                this.Invoke((MethodInvoker)delegate
                {
                    StatusText.Text = "Something should happen";
                });
            }
            else
            {
                StatusText.Text = "Something should happen";
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            StatusText.Text = "It works!";
        }
    }
}
BendEg
  • 20,098
  • 17
  • 57
  • 131
  • Unfortunately this isn't working. But it's so simple it should. – JL. Jan 27 '15 at 12:37
  • @JL. please check my example, maybe it contains some hints :) – BendEg Jan 27 '15 at 12:42
  • I'm running this in the context of a coded ui test, and I think it has to do with the test execution, rather than code. I tried every single example I could find on stack and nothing worked. – JL. Jan 27 '15 at 13:26
-1

One way to make this work is to use a timer that does

StatusText.Text= yourstring;

Every n milliseconds, and make your thread update the 'yourstring' variable to whatever you want.