views:

2547

answers:

7

a while back I ran across a situation where we needed to display message-boxes to the user for notifications but we could not use MessageBox.Show because it blocks the GUI thread (so nothing on the screen gets updated while the dialog is active). Any suggestions on an alternative?

[I coded an alternative at the time but I don't like it. I'll post it as an answer if nothing better appears though]

EDIT: the dialog must float on top of the main window; i don't care if it appears in the taskbar or not. More than one dialog may be active at once in certain circumstances.

ADDENDUM: my solution was a base form that provided OK and CANCEL buttons to emit Completed and Cancelled events; OK called a virtual ValidateData for subclass override. The calling form used properties to avoid recreating the form each time (the form was just hidden instead of closed) and kept a dictionary of active forms to prevent the same form from being activated more than once. This looks like a modal form, supports multiple pop-up forms at once, but does not tie up the main GUI thread.

+1  A: 

I would solve this by using a non-modal dialog box or maybe some tooltips depending on the specific requirements.

rslite
+1  A: 

If you don't want it blocking, I'd just create your own simple form to do the display. That is how I have completed items for clients before when a non-blocking solution was needed. But keep in mind that if you do it as non-blocking that users could get multiples up and be overwhelmed if they are really "you must act" type items.

Mitchel Sellers
+3  A: 

I agree with rslite and Mitchel Sellers. Creating a non-Modal form to display the information needed is the best route to go. If you have multiple messages, you might want to consider putting them into a ListBox and have the user double-click on them to get the full information needing to be displayed.

JFV
this is basically what i had to do; the non-modal form was not fun but works ok - it looks modal, but really isn't ;-)
Steven A. Lowe
A: 

If you want the MessageBox look and feel just show it in a background thread.

ThreadPool.QueueUserWorkItem( (state) =>
    {
         MessageBox.Show("Your message");
    });

(code not tested)

Maurice
I doubt this will work, since MessageBox relies on forms and forms can only be accessed from the main thread. Even if it works, you should not mess up with it by calling SWF on a background thread.
OregonGhost
Does not work. I have tried it before for the same exact purpose. The form is not shown modally.
Ed Swangren
Wasn't the point not to block the UI thread? So showing the MessageBox is a non modal way is the whole point.
Maurice
Yes, but SWF is not thread-safe.
OregonGhost
+2  A: 

I suggest going with a non-modal approach, like others said, but a little more specific:

  • If you just want a notification, you may try a balloon tip (TNA or your own), or a window that is like the Outlook mail notification or the notification many instant messengers like Trillian display.
  • If you just want to give the user a chance to act, use a non-modal form but remember that he might very well just click it away.
  • If the user MUST act upon your message, you should go modal. Note that the owner window will still be painted and you can refresh your GUI - a modal dialog, after all, has a message pump, otherwise it would not work. I did something like that recently, we had a background worker thread pool that would carry on any actions and fire events for the GUI to refresh, and a modal wait dialog that still got its messages pump. The owner window did update with the background action as expected.
OregonGhost
A: 

thanks to everyone who contributed suggestions, it seems that my solution was about right ;-)

my solution was a base form that provided OK and CANCEL buttons to emit Completed and Cancelled events; OK called a virtual ValidateData for subclass override. The calling form used properties to avoid recreating the form each time (the form was just hidden instead of closed) and kept a dictionary of active forms to prevent the same form from being activated more than once. This looks like a modal form, supports multiple pop-up forms at once, but does not tie up the main GUI thread.

Steven A. Lowe
+1  A: 

What about adding a NotifyIcon to your application and displaying a balloon tip. The down side is that the notification will disappear after a short time, but maybe that's best for your users if they don't need to take action.

Don Kirkby