Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a winforms application, how can you run a messagebox from a background worker that must always be in the foreground?

Tags:

c#

winforms

Right now, I'm using a background worker thread to check something every so often and if the conditions are met a messagebox is generated.

I didn't notice for awhile that because I'm calling the messagebox in the background worker I lose the usual messagebox behavior of not letting the user click back on the main form before they click yes/no/cancel on the messagebox.

So, is there some option on the messagebox to keep it in the foreground always? Or is it possible to send a message from the background worker to the main form so I can generate the messagebox from there? Is there another way?

Thanks

Isaac

like image 857
Isaac Bolinger Avatar asked Jul 19 '11 23:07

Isaac Bolinger


2 Answers

A background worker is a different thread than your windows form. Therefor you need to let your background worker somehow return information back to the main thread. In the example below, I use the reportProgress functionality of the backgroundworker, as the event is triggered on the windows form thread.

public partial class Form1 : Form
{
    enum states
    {
        Message1,
        Message2
    }
    BackgroundWorker worker;

    public Form1()
    {
        InitializeComponent();
        worker = new BackgroundWorker();
        worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
        worker.WorkerReportsProgress = true;
        worker.DoWork += new DoWorkEventHandler(worker_DoWork);
    }

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        //Fake some work, report progress
        worker.ReportProgress(0, states.Message1);
    }

    void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        states state = (states)e.UserState;
        if (state == states.Message1) MessageBox.Show("This should hold the form");
    }

    private void button1_Click(object sender, EventArgs e)
    {
        worker.RunWorkerAsync();
    }

}

Note: The background worker will NOT halt at reportProgress. If you want your bgworker to wait until the mbox is pressed, you need to make a halt something manually for it.

like image 78
Marking Avatar answered Nov 20 '22 08:11

Marking


You can use the Invoke method of the Form1 class to invoke that form's UI thread.

this.Invoke(() => MessageBox.Show("Hi"));
like image 44
scottm Avatar answered Nov 20 '22 09:11

scottm