System.Windows.MessageBox не дожидается ввода пользователя перед тем, как отправиться в пуф!
... и не имеет никакого смысла, почему. Т-Т
В моем обработчике событий Application_Startup
у меня есть код, который выглядит примерно так:
private void Application_Startup(object sender, StartupEventArgs e)
{
string errorMessage;
if(CheckStartUpConditions(out errorMessage))
{
(new MainWindow()).Show();
}
else
{
MessageBox.Show(errorMessage, "Application Startup",
MessageBoxButton.OK, MessageBoxImage.Error);
Shutdown();
}
}
private bool CheckStartUpConditions(out string errorMessage)
{
errorMessage = string.Empty;
if(...)
errorMessage += "Please login to xxx. ";
if(...)
errorMessage += "Please install xxx.";
if(string.IsNullOrEmpty(errorMessage))
return true;
else
return false;
}
В окне сообщения появляется краткий вид, как секунда, прежде чем перейти в "POOF!". Это не ждет, когда я нажму "ОК" или на кнопку "X". Я очень сомневаюсь, почему это происходит, поэтому любая помощь будет очень признательна.
Я пробовал комментировать вызов Shutdown
только для ударов и хихиканья, и он по-прежнему ведет себя одинаково.
Кроме того, приложение также имеет SplashScreen
, поэтому я не знаю, будет ли это делать это.
EDIT: я добавил больше кода, если это поможет. В окне сообщения отображается правильное сообщение об ошибке. Просто не останетесь достаточно долго, чтобы пользователи могли его прочитать. > : (
ИЗМЕНИТЬ ЧАСТЬ 2: Хорошо... Думаю, я нашел преступника.:( Я изменил действие сборки на изображении, которое я использую в качестве своего всплеска от SplashScreen до None, и окно сообщения теперь останется и ждет ввода пользователя. Я не понимаю, почему SplashScreen прикручивает MessageBox. > : (
Ответы
Ответ 1
Попробуйте использовать перегрузку, которая принимает параметр System.Windows.Window
и передает значение Null
, чтобы сделать MessageBox верхним окном вашего приложения, которое не зависит от всех других окон, которые могут существовать. Я думаю, ваш MessageBox получает собственность за брандмауэр. Когда заставка закрыта, структура закрывает MessageBox. Поэтому сделать ваш MessageBox бесхозным должен сделать трюк.
Ответ 2
На основе предложения Алексея Иванова я успешно использовал новое окно в качестве родительского
System.Windows.Forms.MessageBox.Show(new System.Windows.Forms.NativeWindow(), errorMessage, "Application Startup", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
Ответ 3
Окно сообщений немедленно исчезает, поскольку у него нет владельца. Если вы укажете опцию MessageBoxOptions.DefaultDesktopOnly
, рабочий стол будет назначен как владелец, и поле сообщения будет работать правильно в приложении без главного окна.
MessageBox.Show(
"Message",
"Title",
MessageBoxButton.YesNoCancel,
MessageBoxImage.Question,
MessageBoxResult.Cancel,
MessageBoxOptions.DefaultDesktopOnly);
Ответ 4
Создайте прозрачное скрытое окно и используйте его как владельца MessageBox:
private Window CreateHiddenWindow()
{
var window = new Window
{
AllowsTransparency = true,
Background = System.Windows.Media.Brushes.Transparent,
WindowStyle = WindowStyle.None,
Top = 0,
Left = 0,
Width = 1,
Height = 1,
ShowInTaskbar = false
};
window.Show();
return window;
}
Ответ 5
Вы можете сохранить свой заставку и использовать стандартный WPF MessageBox, если вы реализуете заставку в коде вместо использования изображения.
App.xaml.cs:
var splashScreen = new SplashScreen("path/to/splash_image.bmp");
splashScreen.Show(false); //make sure to use 'false' here to prevent auto-closing
string errorMessage;
if(CheckStartUpConditions(out errorMessage))
{
(new MainWindow()).Show();
}
else
{
//standard WPF MessageBox may now be used here
MessageBox.Show(errorMessage, "Application Startup",
MessageBoxButton.OK, MessageBoxImage.Error);
Shutdown();
}
//explicitly close the splash screen now
splashScreen.Close(TimeSpan.FromSeconds(1));
Ответ 6
Алексей прав, заставка закрывает окно сообщения.
Простым способом избежать этого является использование собственной функции MessageBox:
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);
public static void Main()
{
...
MessageBox(new IntPtr(0), "Hello World!", "MyApp", 0);
Ответ 7
Вам нужно сообщить WPF, что он не выключается, когда делает первое окно. Посмотри на это:
http://msdn.microsoft.com/en-us/library/system.windows.application.shutdownmode.aspx. Вы хотите явно отключить приложение (а не после закрытия первого окна):
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
ShutdownMode="OnExplicitShutdown">
</Application>
Другой вариант - установить MainWindow как StartupUri (вместо вашего заставки), а затем загрузить ваш заставку в событие MainWindow. Затем вы будете делать то, что нужно для загрузки или времени, вам нужно скрыть свой заставку и снова показать главное окно.