简体   繁体   English

如果在主 window 之前显示任何 window,则应用程序关闭

[英]Application closes if any window is shown before the main window

I have a very puzzling case.我有一个非常令人费解的案例。 During the initialization of my application, before any windows are shown, this function deserializes application settings from XML file, but if deserialization function throws any errors, it displays an error message to the user (which is a custom-made WPF dialog), and once that message dialog is closed, it creates new instance of the settings, and continues the initialization: During the initialization of my application, before any windows are shown, this function deserializes application settings from XML file, but if deserialization function throws any errors, it displays an error message to the user (which is a custom-made WPF dialog), and一旦该消息对话框关闭,它会创建新的设置实例,并继续初始化:

Public Function LoadSettings()
    Try
        Return DeserializeFromXML(settingsPath)
    Catch ex As Exception
        Msg.ShowMessage(Msg.corruptedSettingsFile)          
        Return new AppSettings
    End Try
End Function

ShowMessage is defined as: ShowMessage 定义为:

Public Function ShowMessage(message As Message) As Boolean
    Dim messageDialog As New MessageDialog(message.Title, message.Content, message.Buttons)
    Return messageDialog.ShowDialog()
End Function

Now, the weird thing is, after that exception is caught, and error message is closed by the user, initialization continues, but when it arrives at mainWindow.Show() , nothing happens.现在,奇怪的是,在捕获到异常并且用户关闭错误消息之后,初始化继续进行,但是当它到达mainWindow.Show()时,什么也没有发生。 Main window is not shown.主 window 未显示。 And once initialization code finishes, the application closes immediately.一旦初始化代码完成,应用程序就会立即关闭。

In my Application Properties, the Shutdown mode is set to "On main window close".在我的应用程序属性中,关闭模式设置为“在主 window 关闭”。 StartupUri is not set, because I want to show that main window exactly when I want, not automatically. StartupUri 没有设置,因为我想在我想要的时候显示主 window,而不是自动显示。 However, for testing, I tried to remove mainWindow.Show() altogether, and set StartupUri to MainWindow.XML , but it doesn't solve the issue either.但是,为了测试,我尝试完全删除mainWindow.Show() ,并将 StartupUri 设置为MainWindow.XML ,但这也不能解决问题。

I have tested that if I do not display that error message to the user, the application loads correctly, either with mainWindow.Show() or with StartupUri.我已经测试过,如果我不向用户显示该错误消息,则应用程序会正确加载,无论是使用mainWindow.Show()还是使用 StartupUri。

Why is this happening?为什么会这样?

EDIT: I forgot to mention, which is probably important, that before the mainWindow.Show() , I also call Application.Current.MainWindow = mainWindow .编辑:我忘了提到,这可能很重要,在mainWindow.Show() ,我也调用Application.Current.MainWindow = mainWindow So in case WPF makes that message dialog main window, this call should override it... But it still doesn't work.因此,如果 WPF 使该消息对话框成为主 window,则此调用应覆盖它...但它仍然不起作用。

EDIT 2: I discovered that if I call Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown before showing the message, and restore it with Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose and also call Application.Current.MainWindow = mainWindow , then the application does not close, and all works correctly.编辑2:我发现如果我在显示消息之前调用Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown并使用Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose恢复它并调用Application.Current.MainWindow = mainWindow ,那么应用程序不关闭,一切正常。 However, this is a horrible solution.然而,这是一个可怕的解决方案。 It is obvious now that the message dialog hijacks the Application.Current.MainWindow .现在很明显,消息对话框劫持了Application.Current.MainWindow How do I stop this behavior on the application level, so that the Application.Current.MainWindow would only get set when I explicitly set it?如何在应用程序级别停止此行为,以便Application.Current.MainWindow仅在我明确设置时才被设置?

you must set MainWindow before calling ShowDialog methed of any other windows.您必须在调用任何其他 windows 的ShowDialog方法之前设置MainWindow The reason of this is: a window that was created in application thread, will set itself as main window if MainWindow was null ;原因是:如果MainWindownull and after ShowDialog was called, you would have any chance to fix this because of modal mode.在调用ShowDialog之后,由于模态模式,您将有机会解决此问题。

// this will work.
private void Application_Startup(object sender, StartupEventArgs e)
{
    var a = new MainWindow();
    var b = new MessageDialog();

    b.ShowDialog();
    a.Show();
}

// this will not.
private void Application_Startup(object sender, StartupEventArgs e)
{
    var b = new MessageDialog();
    b.ShowDialog(); //app shutdown at this point

    var a = new MainWindow();
    a.Show();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM