WPF модальное окно прогресса

Я прошу прощения, если на этот вопрос отвечали сотни раз, но я не могу найти ответ, который работает для меня. Я хотел бы создать модальное окно, которое показывает различные сообщения о прогрессе, в то время как мое приложение выполняет долго выполняющиеся задачи. Эти задачи выполняются в отдельном потоке, и я могу обновлять текст в окне прогресса на разных этапах процесса. Связь между потоками все работает хорошо. Проблема в том, что я не могу заставить окно быть поверх только других окон приложений (не всех приложений на компьютере), оставаться на вершине, предотвращать взаимодействие с родительским окном и все еще разрешать работу продолжать.

Вот что я пробовал до сих пор:

Во-первых, мое всплывающее окно - это пользовательский класс, который расширяет класс Window и имеет методы для обновления окна сообщения. Вначале я создаю новый экземпляр класса splash и показываю / скрываю его по мере необходимости.

В простейших случаях я создаю экземпляр окна и вызываю.Show() в теме:

//from inside my secondary thread
this._splash.Dispatcher.Invoke(new Action(() => this._splash.Show());

//Do things
//update splash text
//Do more things

//close the splash when done
this._splash.Dispatcher.Invoke(new Action(() => this._splash.Hide());

Это правильно отображает окно и продолжает выполнять мой код для обработки задач инициализации, но позволяет мне щелкнуть по родительскому окну и перенести его на передний план.

Затем я попытался отключить главное окно и включить его позже:

Application.Current.Dispatcher.Invoke(new Action(() => this.MainWindow.IsEnabled = false));

//show splash, do things, etc

Application.Current.Dispatcher.Invoke(new Action(() => this.MainWindow.IsEnabled = true));

Это отключает все элементы в окне, но я все еще могу щелкнуть главное окно и вывести его перед заставкой, а это не то, что мне нужно.

Затем я попытался использовать свойство topmost в всплывающем окне. Это держит его перед всем, и в сочетании с установкой свойства IsEnabled главного окна я мог бы предотвратить взаимодействие, но это заставляет экран-заставку появляться перед ВСЕМ, включая другие приложения. Я тоже этого не хочу. Я просто хочу, чтобы это было самое верхнее окно в ЭТОМ приложении.

Тогда я нашел сообщения об использовании.ShowDialog() вместо.Show(), Я попробовал это, и он правильно показал диалог и не позволил мне нажать на родительское окно, но вызывая.ShowDialog() заставляет программу зависать, ожидая, пока вы закроете диалог, прежде чем она продолжит выполнение кода. Это, очевидно, тоже не то, что я хочу. Я полагаю, я мог бы позвонитьShowDialog() в другом потоке, чтобы этот поток зависал, но поток, выполняющий работу, не ... это рекомендуемый метод?

Я также рассмотрел возможность вообще не использовать окно и вместо этого помещать полноразмерный элемент окна перед всем остальным на странице. Это будет работать за исключением того, что у меня есть другие окна, которые я открываю, и я хотел бы иметь возможность использовать заставку, когда они тоже открыты. Если бы я использовал элемент окна, мне пришлось бы заново создавать его в каждом окне, и я бы не смог использовать свой удобныйUpdateSplashText метод в моем собственном классе заставки.

Так что это подводит меня к вопросу. Как правильно справиться с этим?

Спасибо за ваше время и извините за длинный вопрос, но детали важны :)

Ответы на вопрос(5)

Ваш ответ на вопрос