21

In my WPF app, I sometimes being up a System.Windows.MessageBox. When it is initially displayed, it is shown on top of my main application window, as I would like. Is there a way that I can force it to ALWAYS remain top of the main window? The problem I have is that when a MessageBox is displayed, users can then click on the main app window and bring it to the front, meaning the MessageBox becomes hidden from view. In this case the user might not realize it's there, or forget about it, and to them, the main app seems to have frozen.

I've read a number of threads about this, but none have resolved the problem for me.

I ought to add that the thread putting up the MessageBox might not be the UI thread. Thanks Tom

Umar Abbas
  • 4,399
  • 1
  • 18
  • 23
Tom Davies
  • 2,386
  • 3
  • 27
  • 44

3 Answers3

56

Use the version of MessageBox.Show that takes a Window "owner" and pass your window.

MessageBox.Show(Application.Current.MainWindow, "Im always on top - of the main window");

If your possibly not on the UI thread try:

string msg="Hello!";
if (Application.Current.Dispatcher.CheckAccess()) {
    MessageBox.Show(Application.Current.MainWindow, msg);
}
else {
    Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(()=>{
        MessageBox.Show(Application.Current.MainWindow, msg);
    }));
}

You can:
1. Invoke to block your thread until MessageBox is dismissed OR
2. BeginInvoke in which case your thread code will continue to execute but UI thread will block on MessageBox until its dismissed).

Ricibob
  • 7,505
  • 5
  • 46
  • 65
  • Is there any other way of doing this if the thread putting up the MessageBox is NOT the UI thread (ie not the thread that owns the MainWindow)? – Tom Davies Apr 10 '12 at 16:34
  • Ah now that info should have gone in the inital question - I suggest adding there now! – Ricibob Apr 10 '12 at 16:36
  • @Ricibob: I had used that approach once for sending messaging to a status bar instead of popping a message box. – Robin Maben Apr 10 '12 at 16:41
  • @TomDavies I've tested this with Invoke and BeginInvoke and it works fine (with different blocking behaviour) in both cases. – Ricibob Apr 10 '12 at 16:57
  • @TomDavies If you are running more than just the UI thread in WPF that would be a good idea ;-) Theres some dispatcher background here: http://stackoverflow.com/questions/7839296/using-the-c-sharp-dispatcher/7839424#7839424 – Ricibob Apr 10 '12 at 17:28
  • I had this problem and came across this posting. After much testing I have determined that my issue was solely the fact that it was not invoking the message box on the UI thread. Passing the window had nothing to do with it. Assuming that you only have the main window displayed and you're not trying to invoke the message box from another window but have it owned by the main window, invoking on the UI thread should fix it and you shouldn't need to pass the window to MessageBox.Show(). – Mageician Apr 01 '14 at 13:31
  • How can I add a title, message button, icon to this ? – mrid Jun 01 '19 at 08:38
1

This is a quick way of putting the Message Box on top of the application windows.

MessageBox.Show(this ,"Output text"));

juni-j
  • 193
  • 7
0

Inside your "public partial class MainWindow : Window" place the following code. So the Invoke will run your code inside UI thread.

void ShowErrorMessage(ERROR err)
{
    this.Dispatcher.Invoke((Action)(() =>
    {
        MessageBox.Show(err.description, err.code.ToString(), MessageBoxButton.OK, MessageBoxImage.Error);
    }));
}
GMG
  • 1,498
  • 14
  • 20