20 Stimmen

System.Windows.MessageBox wartet nicht auf die Benutzereingabe, bevor es verschwindet!

...und es ergibt keinen Sinn warum. T-T

In meinem Application_Startup Ereignishandler habe ich Code, der ungefähr so aussieht:

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 += "Bitte bei xxx anmelden. ";

    if(...)
        errorMessage += "Bitte xxx installieren.";

    if(string.IsNullOrEmpty(errorMessage))
        return true;
    else
        return false;
}

Die Meldung erscheint für etwa eine Sekunde, bevor sie "POOF!" verschwindet. Sie wartet nicht darauf, dass ich auf "OK" oder die "X"-Schaltfläche klicke. Ich bin wirklich ratlos, warum dies passiert, also wäre jede Hilfe sehr geschätzt.

Ich habe versucht, den Aufruf von Shutdown nur zum Spaß auszukommentieren, und es verhält sich immer noch genauso.

Außerdem hat die Anwendung auch einen SplashScreen, also weiß ich nicht, ob das dies beeinflusst.

EDIT: Ich habe mehr Code hinzugefügt, falls das hilft. Die Meldungsbox zeigt die richtige Fehlermeldung an. Aber sie bleibt nicht lange genug für die Benutzer sichtbar, um sie zu lesen. >:(

EDIT TEIL 2: Okay...ich glaube, ich habe den Übeltäter gefunden. :( Ich habe die Build-Aktion des Bildes, das ich als Splash verwende, von SplashScreen auf None geändert und die Meldungsbox bleibt nun stehen und wartet auf Benutzereingabe. Ich verstehe nicht, warum der SplashScreen die Nachrichtenbox durcheinander bringt. >:(

0 Stimmen

Ich kann dieses Problem nicht reproduzieren. Ich habe eine MessageBox in diesem Ereignis in einer Testanwendung platziert und sie bleibt auf dem Bildschirm, bis ich sie schließe. Können Sie eine neue Testanwendung auf Ihrem Computer erstellen und es dort versuchen? Vielleicht handelt es sich um etwas Spezifisches für Ihre Konfiguration oder Ihr Projekt. Wenn Sie es in einer neuen Anwendung durchführen würden, könnten wir feststellen, ob es an Ihrem Visual Studio oder Ihrem Computer liegt oder an Ihrer Anwendung selbst.

0 Stimmen

Hast du in deiner Test-App einen Splashscreen verwendet? Danke!!!

2 Stimmen

Ich vermute, dass dein Problem darin besteht, dass das WPF-Framework denkt, dass dein Splashscreen das Hauptformular ist und die App schließt, wenn es geschlossen wird. Aber ich kenne mich nicht mit WPF aus und kann daher nicht raten, wie man das untersuchen kann!

30voto

Russell Phillips Punkte 699

Der Message-Box verschwindet sofort, weil er keinen Besitzer hat. Wenn Sie die Option MessageBoxOptions.DefaultDesktopOnly angeben, wird der Desktop als Besitzer zugewiesen und die Message-Box funktioniert korrekt in einer Anwendung ohne Hauptfenster.

MessageBox.Show(
    "Nachricht", 
    "Titel",
    MessageBoxButton.YesNoCancel, 
    MessageBoxImage.Question, 
    MessageBoxResult.Cancel,
    MessageBoxOptions.DefaultDesktopOnly);

2 Stimmen

Dies funktioniert großartig. Die einfachste Lösung von allen.

14voto

Neil Punkte 3681

Basierend auf dem Vorschlag von Alexey Ivanov habe ich erfolgreich ein neues Fenster als Elternfenster verwendet

System.Windows.Forms.MessageBox.Show(new System.Windows.Forms.NativeWindow(), errorMessage, "Anwendungsstart", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

1 Stimmen

Verwenden Sie also einfach das WinForms-Meldungsfenster anstelle des WPF-Meldungsfensters. Dies hat bei mir funktioniert, als ich ein Problem mit einer Tray-Anwendung hatte, die kein Hauptformular hatte. Es sollte beachtet werden, dass dies eine neue Abhängigkeit hinzufügt, die eine WPF-Anwendung normalerweise nicht haben würde.

0 Stimmen

Dies ist die beste Antwort. Ich hatte genau das gleiche Problem wie der OP. Seltsamerweise hat der SplashScreen das Verhalten der Nachrichtenbox beeinträchtigt.

0 Stimmen

Mit einer WPF MessageBox funktioniert dieser Trick mit new Window() nicht.

7voto

Alexey Ivanov Punkte 11216

Versuchen Sie, eine Überladung zu verwenden, die einen System.Windows.Window-Parameter akzeptiert und den Wert Null übergibt, um Ihren MessageBox zu einem Top-Level-Fenster Ihrer Anwendung zu machen, das unabhängig von allen anderen vorhandenen Fenstern ist. Ich vermute, dass Ihr MessageBox im Besitz des Splashscreen-Formulars ist. Wenn der Splashscreen geschlossen wird, schließt das Framework den MessageBox. Daher sollte es ausreichen, Ihren MessageBox besitzerlos zu machen.

2 Stimmen

Die Überlastung, die einen Fensterbesitzer bereitstellt, lässt mich nicht null übergeben, aber diese Antwort erklärt, was meine Leiden verursacht. :)

0 Stimmen

@townsean Ich denke, du kannst eine Klasse erstellen, die das IWin32Window-Interface implementiert und null als Wert der Handle-Eigenschaft zurückgibt. Hoffe, es hilft.

0 Stimmen

Ich habe das gleiche Problem beim Herunterfahren. Ich dachte, die MessageBox würde stehen bleiben, bis der Benutzer auf "OK" drückt und dann den restlichen Code ausführt, einschließlich Current.Shutdown(). Natürlich gibt es hier keinen Splash-Screen, also bin ich mir nicht sicher, was passiert.

4voto

andrey.tsykunov Punkte 2806

Erstellen Sie ein transparentes verstecktes Fenster und verwenden Sie es als Besitzer des 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;
        }

3voto

HotN Punkte 4029

Sie können Ihren Startbildschirm beibehalten und eine Standard-WPF-MessageBox verwenden, wenn Sie den Startbildschirm im Code implementieren, anstatt ihn als Bildbaumaßnahme zu verwenden.

App.xaml.cs:

var splashScreen = new SplashScreen("pfad/zur/splash_image.bmp");
splashScreen.Show(false); //Vergewissern Sie sich, hier 'false' zu verwenden, um das automatische Schließen zu verhindern

string fehlermeldung;

if(CheckStartUpConditions(out fehlermeldung))
{
    (new MainWindow()).Show();
}
else
{
    //Standard-WPF-MessageBox kann jetzt hier verwendet werden
    MessageBox.Show(fehlermeldung, "Anwendungsstart", 
        MessageBoxButton.OK, MessageBoxImage.Error);

    Shutdown();
}

//schließen Sie den Startbildschirm jetzt explizit
splashScreen.Close(TimeSpan.FromSeconds(1));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X