25

How might one go about creating a Modeless MessageBox? Do I have to just create my own Windows Form class and use that? If so, is there an easy way of adding a warning icon (rather than inserting my own image of one) and resizing based on text volume?

Smashery
  • 57,848
  • 30
  • 97
  • 128

7 Answers7

56

If you need a message box that just displays itself while your code continues running in the background (the box is still modal and will prevent the user from using other windows until OK is clicked), you can always start the message box in its own thread and continue doing what ever you do in the original thread:

    // Do stuff before.
    // Start the message box -thread:
    new Thread(new ThreadStart(delegate
    {
      MessageBox.Show
      (
        "Hey user, stuff runs in the background!", 
        "Message",
        MessageBoxButtons.OK,
        MessageBoxIcon.Warning
      );
    })).Start();
    // Continue doing stuff while the message box is visible to the user.
    // The message box thread will end itself when the user clicks OK.
tojotamies
  • 561
  • 4
  • 4
  • 3
    Thanks, this actually answered the question directly. – eruciform Mar 30 '13 at 01:44
  • You can use `MessageBox.Show` from a thread, but not construct and show an entire `Form`? Is there any .NET way to simulate a `MessageBox` using a form? (perhaps i need a MessageBox with more choices than a standard message box) – Ian Boyd Oct 25 '13 at 19:39
  • This works for me and, contrary to what tojotamies said, it is not modal, but modeless. – ajs410 Jan 31 '17 at 22:06
  • 3
    You can make it a little more concise: `new Thread(() => { MessageBox.Show("Hi"); }).Start();` – Wayne Uroda Feb 12 '17 at 13:11
6

You'll have to create a Form and use Show() to display it Modeless. MessageBox.Show(...) behaved Modal as seen in the example by ghiboz; "Description of the message" is displayed until the user presses a button.

With MessageBox.Show(...) you get the result as soon as the messagebox is closed; with a modeless message box, your code will have to have a mechanism such as an event to react when the user eventually selects something on your message box.

John Warlow
  • 2,922
  • 1
  • 34
  • 49
  • This was my initial implementation - unfortunately, it causes my program to crash when being launched from a background process for some reason. Nonetheless, there doesn't seem to be any better solution. Thanks. – Smashery Jun 19 '10 at 03:19
  • UI stuff can't be manipulated from a secondary thread. Take a look at the Dispatcher to move it into the primary thread. – Jeff Jun 13 '12 at 02:50
1

Short of writing the code, you could create a small form that in the constructor does the following

  • Takes a parameter string as the message to display
  • Fills up a label on the form with this string
  • Loads an icon with one of the following (pass in an Enum to the constructor)
    • SystemIcons.Application
    • SystemIcons.Asterix
    • SystemIcons.Error
    • SystemIcons.Exclamation
    • SystemIcons.Hand
    • SystemIcons.Information
    • SystemIcons.Question
    • SystemIcons.Shield
    • SystemIcons.Warning
    • SystemIcons.WinLogo
  • Calls Show() which will cause it to be a modal dialog

If you really wanted, you could listen to an event that is fired when the OK button is pushed.

Stefan Valianu
  • 1,370
  • 2
  • 13
  • 24
0

You can use the standard system warning icon using SystemIcons

Shay Erlichmen
  • 31,691
  • 7
  • 68
  • 87
0

You have to either use form and call showDialog()

And for icons use

MessageBoxIcon.Warning

prashant
  • 361
  • 9
  • 26
-1

Note: this will create a Modal dialog box, which is not what the question is asking

here is a sample code

if (MessageBox.Show("Description of the message", "Caption text", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.Yes)
{
    // Do some stuff if yes pressed
}
else
{
    // no pressed
}
Smashery
  • 57,848
  • 30
  • 97
  • 128
ghiboz
  • 7,863
  • 21
  • 85
  • 131
  • I'm after a modeless dialog; not a modal one. – Smashery Jun 17 '10 at 07:16
  • 1
    This answer was receiving votes, despite being the opposite of what I asked for (modeless). So that others don't think this answer will solve this particular problem, I have edited the response with a disclaimer. – Smashery Jun 19 '10 at 03:22
  • +1 Thanks, Found this when looking for how to make a modal MessageBox. – Martin Oct 13 '13 at 10:03
-1

//no commnet

object sync = new object();
ManualResetEvent Wait = new ManualResetEvent();
//you should create a place holder named MessageData for Message Data.
List<MessageData> Messages = new List<MessageData>();
internal void ShowMessage(string Test, string Title, ....)
{
    MessageData MSG = new MessageData(Test, Title);
    Wait.Set();
    lock(sync) Messages.Add(MSG);
}
// another thread should run here.
void Private_Show()
{
    while(true)
{
        while(Messsages.Count != 0)
        {
            MessageData md;
            lock(sync)
            {
                md = List[0];
                List.RemoveAt(0);
            }
            MessageBox.Show(md.Text, md.Title, md....);
        }
        Wait.WaitOne();
    }
}

needs more threads and more code(I don't have enough time to write) for concurrent messageboxes.

Behrooz
  • 1,696
  • 2
  • 32
  • 54