How to change window state of Form, on a different thread?

21.8k Views Asked by At

Does anyone know how I can change the window state of a form, from another thread? This is the code I'm using:

    private void button4_Click(object sender, EventArgs e)
    {
            string pathe = label1.Text;
            string name = Path.GetFileName(pathe);
            pathe = pathe.Replace(name, "");
            string runpath = label2.Text;
            Process process;
            process = new Process();

            process.EnableRaisingEvents = true;
            process.Exited += new System.EventHandler(process_Exited);

            process.StartInfo.FileName = @runpath;
            process.StartInfo.WorkingDirectory = @pathe;
            process.Start();
            WindowState = FormWindowState.Minimized;
    }
    private void process_Exited(object sender, EventArgs e)
    {
        this.WindowState = FormWindowState.Normal;
    }

It's meant to run a program and minimize, then return to the normal state once the program has closed. Although I get this error "Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on." Any idea how to get this to work?

5

There are 5 best solutions below

3
On BEST ANSWER

This will work in .NET 3.5:

Invoke(new Action(() => { this.WindowState = FormWindowState.Normal; }));

Or 2.0:

Invoke(new MethodInvoker(delegate { this.WindowState = FormWindowState.Normal; }));
1
On

this will solve your problem add it in the form_load event

 System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
0
On

Just search this string in StackOverflow "Cross-thread operation not valid" or Google. Please, don't be that lazy.

1
On

See What’s the difference between Invoke() and BeginInvoke() on this site. The "chosen" answer gives a good explanation of what you're supposed to do.

Long story short, you want different THREADS not making a new process entirely (or highly unlikely you want that), and you probably want to use Invoke() and not BeginInvoke() which is asynchronous.

0
On

Add this line of code to the Click event handler:

process.SynchronizingObject = this;