MessageBox с деталями исключения немедленно исчезает, если использовать заставку в WPF 4.0 - PullRequest
8 голосов
/ 08 октября 2010

Мое настольное WPF-приложение (4.0) работает с БД, и для этого ему нужно установить соединение с SQL Server при запуске приложения.Конечно, эта операция занимает некоторое время, и пользователю нужно подождать несколько секунд (3-5), пока .Net Framework запускается и подключается к SQL Server.

При необходимости в таких случаях я решил использовать всплескэкран.Я добавил картинку к решению, установил действие сборки как «Заставка», скомпилировал мое приложение, все работает!Если попытка подключиться к SQL Server не удалась (например, сервер недоступен), мое приложение выдает исключение, и я показываю пользователю MessageBox с подробностями предупреждения и исключения, пользователь нажимает OK и завершает работу приложения (Application.Current.Shutdown()).

До того, как я добавил заставку, вся эта логика раньше работала идеально, но теперь, с добавлением заставки, если я запускаю приложение, когда SQL Server недоступен, приложение выдает исключение (как я просил в моем коде), но MessageBox с уведомлением появляется на 1-2 секунды и исчезает без какого-либо взаимодействия с пользователем, пользователь даже не может прочитать то, что на нем написано.

Я обнаружил, что если я попытаюсь показать 2 MessagBoxes, топервый появится и исчезнет немедленно, но второй останется до тех пор, пока пользователь не нажмет OK.

Мой вопрос: как решить эту проблему?Я хочу использовать заставку и показать один MessageBox, если было сгенерировано исключение, и позволить пользователю решать, когда его закрывать (пользователь нажимает кнопку OK).

Вот блок-схема, описывающая логикумоего приложения:

Без исключения (хороший сценарий): Запустить приложение → Заставка → if(isConnectedToSQL=true) → Показать главное окно…

За исключением (плохой сценарий): Запустить приложение → Заставка →if(isConnectedToSQL=false) → Бросить исключение → Показать MessageBox с подробностями об исключении → Пользователь нажимает ОК → Закрыть приложение.

Ответы [ 3 ]

7 голосов
/ 08 октября 2010

Причина заключается в том, что SplashScreen использует BeginInvoke для закрытия самого себя. Я не мог точно определить, где закрывается MessageBox *, но я видел простое исправление:

Не используйте MessageBox.

Создайте окно ошибки, назовем его «ErrorWindow.xaml». Используйте это окно, чтобы отобразить сообщение об ошибке для пользователя и ответить на кнопку OK.

Следуйте этому руководству , чтобы объявить свою собственную процедуру Main и изменить ее следующим образом:

Отредактировано, чтобы показать, как вы можете передавать информацию в ErrorWindow.

public static void Main()
{
    SplashScreen splashScreen = new SplashScreen("whatever.jpg");
    splashScreen.Show(true);
    string errorMessage;
    bool dataLoaded = LoadDataFromDatabase(out errorMessage);
    WpfApplication1.App app = new WpfApplication1.App();
    Window windowToRun = dataLoaded ? (Window)new MainWindow() : (Window)new ErrorWindow { ErrorMessage = errorMessage };
    app.Run(windowToRun);
}
  • Я предполагаю, что SplashScreen.Show и Application.Run - это два отдельных сообщения. Первый завершается вызовом PostQuitMessage. Это объясняет, почему закрывается MessageBox.
2 голосов
/ 16 марта 2011

По схожему вопросу StackOverflow я перечислил несколько разных подходов к решению этой проблемы.

Некоторые из этих трюков могут оказаться полезными, если подход @ Tergiver не работает для вашего приложения.

как установить wpf MessageBox.Owner в окно рабочего стола, потому что SplashScreen закрывает MessageBox

0 голосов
/ 14 ноября 2011

Учитывая описание проблемы на https://connect.microsoft.com/VisualStudio/feedback/details/381980/wpf-splashscreen-closes-messagebox#tabs, один из способов решить это - DllImport SetActiveWindow и вызвать его как SetActiveWindow (IntPtr.Zero) непосредственно перед вызовом MessageBox.Show.Тогда окно сообщения не получит заставку как родитель и не закроется, когда заставка закроется сама.

...