views:

458

answers:

4

Hello. Does anyone know how I can chage 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? Thanks.

+1  A: 

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

Andrey
Sorry. Will do next time.
Joey Morani
+2  A: 

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; }));
Adam Robinson
Thanks. That worked.
Joey Morani
In 2.0 you can just go `Invoke(new Action<string>(delegate { this.WindowState = FormWindowState.Normal; }));` as well, not MethodInvoker if you don't want to. Action<T> exists in 2.0, it's Func<> that doesn't.
Kevin
@Kevin: True, but Action (no `<T>`) only exists in 3.5
Adam Robinson
@Adam Robinson - That's true, with no type it's 3.5.
Kevin
+1  A: 

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.

Kevin
@Kevin: Considering he's starting an external application and waiting for it to exit, it seems like another process is *exactly* what he wants (in fact, requires).
Adam Robinson
+1  A: 

Add this line of code to the Click event handler:

process.SynchronizingObject = this;
Hans Passant