Подтвердить что ты не робот

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. > : (

4b9b3361

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