19

Ok, I'm looking for something pretty simple: creating a MessageBox that doesn't stop my code.

I'm guessing I'll have to create a different thread or something? Please advise on the best way to accomplish this.

Thanks!

sooprise
  • 22,657
  • 67
  • 188
  • 276

2 Answers2

15

You could spin up another message pump by calling it on separate thread. MessageBox.Show pumps message so it is safe to do without a call to Application.Run.

public void ShowMessageBox()
{
  var thread = new Thread(
    () =>
    {
      MessageBox.Show(...);
    });
  thread.Start();
}

Edit:

I probably should mention that I do not recommend doing this. It can cause other problems. For example, if you have two threads pumping messages then it is possible for the message box to get stuck behind another form with no way to make it go away if the form is waiting for someone to close the message box. You really should try to figure out another way around the problem.

Brian Gideon
  • 47,849
  • 13
  • 107
  • 150
  • 1
    `ThreadPool.QueueUserWorkItem(delegate {MessageBox.Show("Text");});` :) – sunside Jul 08 '10 at 16:24
  • 2
    @Markus: That would do the trick as well except it would hang up a `ThreadPool` thread which would not be a good practice generally speaking. – Brian Gideon Jul 08 '10 at 16:31
  • In Brian's code example, how to I stop the thread (and close it?) when the messagebox is closed. Multithreading is very mysterious and new to me, so the inner workings of having another thread are beyond me. – sooprise Jul 08 '10 at 18:25
  • 1
    @Soo: You don't have to do anything special. Once the `MessageBox` is closed the thread will end gracefully. – Brian Gideon Jul 08 '10 at 19:32
  • Thank you for that solution, it seems to be obvious, but i've totally forgotten to do something like that ;) – Wojciech Kulik Apr 01 '12 at 11:28
  • @BrianGideon But how would I get the return value from MessageBox outside the thread? – diogocarmo Mar 01 '13 at 12:23
  • I'm not sure if I got you right, but I think in your example one could easily move out the window on most OSs by holding a specific key, usually Alt, and clicking the window. Not sure about Windows tho, but even there one could just press Alt+Tab to switch to the MessageBox, and press esape, or enter, or alt+f4. – Hi-Angel Apr 07 '16 at 14:37
  • @Hi-Angel: Possibly yes, but I think users might still find that annoying. – Brian Gideon Apr 07 '16 at 18:49
13

No, You're going to have to make your own message box form. the MessageBox class only supports behavior similar to .ShowDialog() which is a modal operation.

Just create a new form that takes parameters and use those to build up a styled message box to your liking.


Update 2014-07-31

In the spirit of maintaining clarity for anyone else who finds this through google I'd like to take a second to explain this a bit more:

Under the hood MessageBox is a fancy C# Wrapper around the Windows SDK user32.dll MessageBox Function and thus behaves exactly the same way (after converting .NET Enums into the integers that represent the same thing in the system call.

What this means is that when you call MessageBox.Show() the call is marshaled out to the OS and will block the current thread until an option is selected or the window is killed. To prevent your code from being halted you need to launch the message box on a seperate thread, but this will mean that any result that comes back from the message box (Yes / No / Ok / Cancel / Etc...) will be returned to the separate thread that was tasked to call the message box.

If you act on the result of this message box launched this way you'll have to Dispatch the result back to the UI Thread for Thread Saftey.

Alternatively you can create your own message box form in WinForms / WPF and call it with the .Show() method. Any click events on the buttons will execute on the UI Thread and you will not have to dispatch the calls back to the UI Thread to manipulate things in the UI.

Aren
  • 54,668
  • 9
  • 68
  • 101
  • Ok gotcha, so I just have to create my own form. Very doable, thanks! – sooprise Jul 08 '10 at 16:10
  • So if I had `Messagebox.Show(MessageBoxButtons.OK)` would the program pause until a user clicks the OK button? Because I want to run my automation process and once the first 2 processes are complete, pause the process via Messagebox, and then after the user clicks on the messagebox, have the next automation process run. – HanH1113 Jul 31 '14 at 13:44
  • @HanH1113 The `MessageBox.Show()` method under the covers effectively runs the same way that `.ShowDialog()` does. It's a blocking operation so execution is halted until the dialog box closes. I have updated my answer to be more clear. – Aren Aug 01 '14 at 00:18