在.NET/WPF中如何强制MessageBox显示在应用程序窗口的顶部

21
在我的WPF应用程序中,有时会出现一个System.Windows.MessageBox。当它最初显示时,它会显示在我的主应用程序窗口的顶部,这正是我想要的。是否有一种方式可以强制它始终保持在主窗口的顶部?我的问题是,当显示MessageBox时,用户可以单击主应用程序窗口并将其置于前台,这意味着MessageBox会被隐藏。在这种情况下,用户可能不会意识到它的存在,或者忘记了它,对他们来说,主应用程序似乎已经冻结了。
我已经阅读了许多关于这个问题的帖子,但没有解决我的问题。
我还应该补充一点,放置MessageBox的线程可能不是UI线程。 谢谢 汤姆
3个回答

56

使用带有窗口“owner”的MessageBox.Show版本,并将您的窗口传递给它。

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

如果你可能不在 UI 线程上,请尝试:

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);
    }));
}

你可以选择:
1. Invoke 来阻塞你的线程,直到 MessageBox 被关闭;或者
2. BeginInvoke ,在这种情况下,你的线程代码将继续执行,但UI线程将被阻塞,直到MessageBox 被关闭)。


如果放置消息框的线程不是UI线程(即不是拥有MainWindow的线程),是否有其他方法来完成这个任务? - Tom Davies
啊,现在这个信息应该放在最初的问题中 - 我建议现在添加进去! - Ricibob
@TomDavies 我已经使用Invoke和BeginInvoke进行了测试,在两种情况下都可以正常工作(具有不同的阻塞行为)。 - Ricibob
@TomDavies 如果你在WPF中运行的不仅仅是UI线程,那么这是一个好主意;-) 这里有一些调度程序的背景:https://dev59.com/-2sz5IYBdhLWcg3wiIOe#7839424 - Ricibob
我遇到了这个问题,并在这篇帖子中找到了解决方法。经过多次测试,我确定我的问题仅仅是因为它没有在UI线程上调用消息框。传递窗口与此无关。假设您只显示了主窗口,并且不是从另一个窗口调用消息框,而是由主窗口拥有它,那么在UI线程上调用应该可以解决问题,您不需要将窗口传递给MessageBox.Show()。 - Mageician
显示剩余2条评论

1
这是一种快速将消息框放置在应用程序窗口顶部的方法。 MessageBox.Show(this ,"输出文本"));

0
在你的"public partial class MainWindow : Window"中加入以下代码。这样,Invoke 将会在 UI 线程执行你的代码。
void ShowErrorMessage(ERROR err)
{
    this.Dispatcher.Invoke((Action)(() =>
    {
        MessageBox.Show(err.description, err.code.ToString(), MessageBoxButton.OK, MessageBoxImage.Error);
    }));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接