WPF MessageBox not waiting for result [WPF NotifyIcon]
Asked Answered
L

2

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?

Loreeloreen answered 14/3, 2014 at 10:57 Comment(3)
I suggest to try this msdn.microsoft.com/ru-ru/library/…Villagomez
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.Immure
A related comment on the WPF NotifyIcon codeproject page.Immure
L
1

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.

Loreeloreen answered 14/3, 2014 at 13:53 Comment(5)
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?Immure
Can you simply not close it, and then close it only when the application closes?Loreeloreen
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.Immure
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.Immure
no no no no no, please dont do this. There is a reason the MessageBox has an overload with MessageBoxOptions in it, use it.Stab
A
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);
Antidromic answered 18/1, 2015 at 19:44 Comment(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.Stopped
L
1

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.

Loreeloreen answered 14/3, 2014 at 13:53 Comment(5)
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?Immure
Can you simply not close it, and then close it only when the application closes?Loreeloreen
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.Immure
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.Immure
no no no no no, please dont do this. There is a reason the MessageBox has an overload with MessageBoxOptions in it, use it.Stab

© 2022 - 2025 — McMap. All rights reserved.