Вопрос по wpf – Принудительно установить MessageBox поверх окна приложения в .net / WPF

15

В моем приложении WPF я иногда бывSystem.Windows.MessageBox. Когда он изначально отображается, он отображается поверх главного окна приложения, как мне хотелось бы. Есть ли способ, которым я могу заставить его ВСЕГДА оставаться сверху главного окна? У меня проблема в том, что когдаMessageBox отображается, пользователи могут затем нажать на главное окно приложения и вывести его на передний план, то естьMessageBox скрывается от глаз. В этом случае пользователь может не осознавать, что он там, или забыть об этом, и им кажется, что основное приложение зависло.

Я читал несколько тем об этом, но ни одна из них не решила проблему для меня.

Я должен добавить, что нить, поднимающаяMessageBox не может быть темой пользовательского интерфейса. Спасибо, Том

Ваш Ответ

3   ответа
43

Используйте версиюMessageBox.Show который берет окно "владелец" и передает ваше окно.

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

Если вы не в потоке пользовательского интерфейса, попробуйте:

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 в этом случае код вашего потока будет продолжать выполняться, но поток пользовательского интерфейса будет блокироваться наMessageBox пока его не уволят).

Есть ли другой способ сделать это, если поток, создающий MessageBox, НЕ является потоком пользовательского интерфейса (т. Е. Не потоком, которому принадлежит MainWindow)? Tom Davies
А теперь эта информация должна была войти в начальный вопрос - я предлагаю добавить туда сейчас! Ricibob
Вы пытались отправить код MessageBox в поток пользовательского интерфейса? Ricibob
@ Ricibob: я использовал этот подход один раз для отправки сообщений в строку состояния вместо того, чтобы открывать окно сообщения. Robin Maben
@ TomDavies Я проверил это с помощью Invoke и BeginInvoke, и оно отлично работает (с различным поведением блокировки) в обоих случаях. Ricibob
1

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

0

Внутри твоего "public partial class MainWindow : Window "поместите следующий код. Таким образом, Invoke выполнит ваш код в потоке пользовательского интерфейса.

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

Похожие вопросы