7

I've some MessageBox that I code like this:

MessageBox.Show(new Form(){TopMost=true, TopLevel=True}, "Message","Title", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

For a better example, I do this for the FormClosing Event:

private void Example_FormClosing(object sender, FormClosingEventArgs e){
MessageBox.Show(new Form(){TopMost=true, TopLevel=True}, "Really close?"," Program", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
}

But, almost every time I've to change of Window on my computer (like return on Visual Studio) before seeing my messagebox and it's not user-friendly and really annoying.

I verified that my principal form was not in TopMost=true, I tried just the TopMost or just the TopLevel,the StartPosition=FormStartPosition.CenterScreen but nothing worked.

[Update]

I tried:

 private void Example_FormClosing(object sender, FormClosingEventArgs e){
    MessageBox.Show(this.Owner, "Really close?"," Program", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
    }

I'd like to have my messageBox on the front of my window and not have to change of window to see it because it's like behind the current window.

Have you an idea to resolve this problem?

Alice
  • 313
  • 2
  • 5
  • 16
  • Please be more clear, not sure what you are asking for. – Harish Apr 09 '13 at 11:51
  • What do you want to achieve? – Max Apr 09 '13 at 11:51
  • owner need to be shown first. – JSJ Apr 09 '13 at 11:53
  • Can you compile it, how TopLevel=True is working? – Kashif Apr 09 '13 at 11:54
  • I'd like to have my messagebox on the front of every else currently opened windows. I used these messagebox to show (for example) that all my datagridview is save on db or to ask the user to put some correct format in a textbox,... The user has to click on Ok, Yes, No or cancel to close this message box and keep going to work – Alice Apr 09 '13 at 11:56

8 Answers8

12

Do it like this:

MessageBox.Show(
    "Message", 
    "Title", 
    MessageBoxButtons.YesNo, 
    MessageBoxIcon.Warning, 
    MessageBoxDefaultButton.Button1, 
    MessageBoxOptions.DefaultDesktopOnly);

It will put it in front of all other windows, including those from other processes (which is what I think you're asking for).

The critical parameter is MessageBoxOptions.DefaultDesktopOnly. Note that this will parent the message box to the default desktop, causing the application calling MessageBox.Show() to lose focus.

(You should really reserve this behaviour for critical messages.)

Alternatively, if your application has a window, call this.BringToFront() before showing the message box by calling MessageBox.Show() with the first parameter set to this. (You'd call this from the window form class).

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
  • Thanks for the tip but yeah, a little bit too drastic – Alice Apr 09 '13 at 12:06
  • Well it's no more drastic than doing it some other way (i.e. putting the window in front of all other windows on the system). Alternatively, you might want to put your application itself to the foreground. – Matthew Watson Apr 09 '13 at 12:14
  • Yes, but I use messagebox for a lot of things and unfortunately, all are important but I can lose focus on the principal window too... But you're solution is great in some case and I probably use it very soon! – Alice Apr 09 '13 at 12:19
  • Could you use the `this.BringToFront()` approach on the main form? – Matthew Watson Apr 09 '13 at 13:17
5

Given an instance of your Form, you can call a MessageBox like this:
MessageBox.show(form, "Message", "Title"); (Check the doc for other parameters.)

However if you want to call this from a background thread (e.g.: BackgroundWorker) you have to use Form.Invoke() like this:

form.Invoke((MethodInvoker)delegate
{
   MessageBox.show(form, "Message", "Title");
});
Lars
  • 500
  • 1
  • 7
  • 22
2

I've answered this here (but since it's a fairly small answer, I'll replicate it):

using (var dummy = new Form() { TopMost = true })
{
    MessageBox.Show(dummy, text, title);
}
Community
  • 1
  • 1
Joel
  • 7,401
  • 4
  • 52
  • 58
0

You're setting the MessageBox owner to a new form that hasn't been shown. Instead of new Form(){TopMost=true, TopLevel=True}, refer to an instance of an existing form that you want the MessageBox on top of.

MrBlue
  • 830
  • 6
  • 13
  • I used my messagebox in the View of the owner window. Did you mean like this : MessageBox.Show(this.owner,.....)? – Alice Apr 09 '13 at 12:07
  • If you're calling it from a form, just `MessageBox.Show(this, ...` would be correct. That said, if you are calling it from a form I believe the owner is implied so you can leave it out entirely. – MrBlue Apr 09 '13 at 12:18
  • That's not a problem to see the owner behind the messagebox, that's the point. But here, I have to change of program (go to visual studio or office,...) and then I saw my messagebox when I came back on my application – Alice Apr 09 '13 at 12:21
  • Have you tried `MessageBox.Show(this, ...`? I have experienced what you're describing and setting the owner of the `MessageBox` explicitly has always resolved it for me. – MrBlue Apr 09 '13 at 12:25
  • Yes I tried.. I really don't understand why it's not working. – Alice Apr 09 '13 at 12:26
0

Further to Lars' answer, I had the same problem and Lars' method worked, but if I then popped up a message from elsewhere that wasn't on top, switched to it, and then the message was called using Lars' method again, it would no longer be on top.

This is the variation that I came up with that works well for me, hope you find it helpful:

This is run from a separate thread, that has a reference to the main application form instance

//Show message on top of all other forms
MainFormInstance.Invoke((MethodInvoker)delegate
{
    Form popup = new Form() { TopMost = true, TopLevel = true };
    MessageBox.Show(popup, "Message", "Title");
});
Jayd
  • 880
  • 1
  • 12
  • 16
0

Try to write generalize logic as:-

public static DialogResult ShowMessage(Form Parent, string Text, string Caption, MessageBoxButtons Buttons, MessageBoxIcon Icon, MessageBoxDefaultButton DefaultButton)
{
    if (Parent != null && Parent.InvokeRequired)
        return (DialogResult) Parent.Invoke(((Func<DialogResult>))(() => MessageBox.Show(Text, Caption, Buttons, Icon, DefaultButton)));
    else
        return (MessageBox.Show(Text, Caption, Buttons, Icon, DefaultButton));
}
DDave
  • 608
  • 6
  • 17
0

I have been playing around with this and running multiple tests on Windows 7/8.1/10 then finally come to a working method to display the message box on top in all the systems mentioned above.

//Create an Empty Form with TopMost & TopLevel attributes.
Form popup = new Form() { TopMost = true, TopLevel = true };

//Running MessageBox on a different Thread

              Invoke((MethodInvoker)delegate {

     DialogResult dialogResult = MessageBox.Show(popup, "Custom Message Here", MessageBoxButtons.YesNo);
              if (dialogResult == DialogResult.Yes)
              {

                  //do something
              }
              else if (dialogResult == DialogResult.No)
              {
                  //do something else
              }

//Or a casual message box

//MessageBox.Show(popup, "Custom Message Here", "Alert");

 });
MrJack Mcfreder
  • 692
  • 1
  • 10
  • 21
-1

just do that as normal (MessageBox.Show(Message);) it's already topmost.

see here and here for information.

Harits Fadillah
  • 341
  • 1
  • 2
  • 8