10

I am using WPF NotifyIcon to create a System Tray service. When I show a messagebox, it shows up for half a second and then disappears immediately without waiting for input.

This kind of situation has happened before, and the usual advice is to use an overload which accepts a Window parameter. However, being a System Tray service, there is no window to use as a parent, and null is not accepted in its place.

Is there any way to make the MessageBox wait for user input short of creating a custom MessageBox window myself?

Community
  • 1
  • 1
Gigi
  • 28,163
  • 29
  • 106
  • 188
  • I suggest to try this http://msdn.microsoft.com/ru-ru/library/system.windows.controls.primitives.popup(v=vs.110).aspx – nuclear sweet Mar 14 '14 at 10:59
  • I am experiencing the same, also when using WPF NotifyIcon, although it seems to be a more general issue. I also noticed that if you trigger two message boxes in a row, the first one is only shown shortly, but the second one stays. – Steven Jeuris Jan 10 '15 at 20:54
  • A related comment [on the WPF NotifyIcon codeproject page](http://www.codeproject.com/Articles/36468/WPF-NotifyIcon?msg=4793248#xx4793248xx). – Steven Jeuris Jan 10 '15 at 21:47

2 Answers2

28

You don't need to create a proxy window for this. Just add MessageBoxOptions.DefaultDesktopOnly to your message box and it will fire on your desktop without disappearing.

Example

MessageBox.Show("My Message", "Title", MessageBoxButton.OK, 
    MessageBoxImage.Information, MessageBoxResult.OK, 
    MessageBoxOptions.DefaultDesktopOnly);
Xcalibur37
  • 2,305
  • 1
  • 17
  • 20
  • 1
    ServiceNotification has the same effect, except the message box is displayed on the active desktop rather than the default one. I assume this plays nicer with multiple monitors. – Grault Jun 03 '15 at 18:55
0

According to the answer here, a workaround is to actually open an invisible window and use that as the parent of the MessageBox:

        Window window = new Window()
        {
            Visibility = Visibility.Hidden,
            // Just hiding the window is not sufficient, as it still temporarily pops up the first time. Therefore, make it transparent.
            AllowsTransparency = true,
            Background = System.Windows.Media.Brushes.Transparent,
            WindowStyle = WindowStyle.None,
            ShowInTaskbar = false
        };

        window.Show();

...then open the MessageBox with the appropriate parameter:

        MessageBox.Show(window, "Titie", "Text");

...and don't forget to close the window when you're done (possibly on application exit):

        window.close();

I tried this and it works well. It's undesirable to have to open an extra window, but it's better than making your own messagebox window just for the sake of making this work.

Steven Jeuris
  • 18,274
  • 9
  • 70
  • 161
Gigi
  • 28,163
  • 29
  • 106
  • 188
  • I need to open this window each and every time a command is triggered from the context menu (and I want to show a `MessageBox`). Doing it once does not suffice. Do you experience the same? – Steven Jeuris Jan 10 '15 at 21:40
  • Can you simply not close it, and then close it only when the application closes? – Gigi Jan 11 '15 at 10:38
  • Sorry for the confusion. What I was referring to was that actually you do not need to pass the first window parameter. **An alternative is simply opening at least one other WPF window prior to calling `MessageBox.Show`**. Strangely enough, this can also be an earlier `MessageBox.Show` which automatically closes! Thus calling `Show()` twice 'works', although is obviously very undesirable. Knowing this, I was looking for a solution so that the `window` parameter doesn't need to be passed constantly. – Steven Jeuris Jan 16 '15 at 00:04
  • However, I couldn't find any, and ended up using this solution as well, using a wrapper class which instantiates the window. Rather than resizing/positioning the window, setting `Visibility = Visibility.Hidden` is probably preferable. If you disagree, feel free to roll back. – Steven Jeuris Jan 16 '15 at 00:06
  • no no no no no, please dont do this. There is a reason the MessageBox has an overload with MessageBoxOptions in it, use it. – Wobbles Aug 13 '16 at 14:46