在缺席的情况下,WPF申请的ShutdownMode是On LastWindowClose。 你的代码显示一个窗口,然后关闭。 因此,最后窗口关闭,申请关闭。 然后,在关闭时,你又展示了另一个窗口。 由于申请被关闭,窗口立即关闭。
因此,一切工作都是由你设计和规划的。
然而,你们想要做的是: 你的窗口首先显示,唯一的窗口应当是“特殊窗口”,关闭后,你希望继续实施,展示你的“主要窗口”,然后在申请(或所有与 app有关的窗口)关闭后退出申请。
最容易的方式是:首先将关闭模式定在“ExplicitShutdown”,然后向“LastWindowClose”或“MainWindowClose”展示主要窗口。 法典:
public static void Main()
{
var app = new App();
app.InitializeComponent();
app.ShutdownMode = ShutdownMode.OnExplicitShutdown;
new DialogWindow().ShowDialog();
var mainWindow = new MainWindow();
app.MainWindow = mainWindow;
app.Run(mainWindow);
// When the window has loaded, it should then set the app.ShutdownMode to what you actually want.
}
EDIT:
I am not sure what exactly you are doing. The code you gave will not compile, since when properly using a WPF application class (with an App.xaml build-action as ApplicationDefinition), a Main method is already defined. If you just have a class derived from Application, you have no InitializeComponent() method. The only way to get you code to compile was by manually changing the build-action to Page. However, in that case, Application.Current == app.
因此,情况如下:
- The application starts. Since no WPF-application has been created so far, Application.Current is null. This also means no dispatcher-loop is running and dispatcher messages are unhandled (note that the dispatcher loop also handles windows messages).
- A new App-object is created. Since Application.Current is null, it sets itself as Application.Current.
- Application.Current.MainWindow is null and Application.Current.Windows is an empty list.
- Since ShutdownMode is OnLastWindowClose, once the last window of the current application (i.e. app) closes, shutdown starts.
- The DialogBox is shown modally. Since no dispatcher-loop is running, the ShowDialog() itself runs a "local" dispatcher-loop.
- Actually this is two parts: First the window is created. It belongs to the current application, so it adds itself to Application.Current.Windows. Since it is the first window shown and Application.Current.MainWindow is null, it also sets itself as main window. Secondly, the window is shown modally.
- Since Application.Current.Windows is now non-empty, once it is empty, shutdown will start.
- The user closes the dialog window. As part of being closed, the window removes itself from Application.Current.Windows. Also, since it is the MainWindow, this is set to null. Since Application.Current.Windows is now empty, shutdown starts. However, since there is no dispatcher-loop running, nothing is done yet (only an internal flag or similar is set).
- If you had used
app.Run(new DialogWindow()); app.Run(new MainWindow());
, you would have an exception while creating the MainWindow, since in this case the dispatcher-loop is running properly. Thus, it can actually shutting itself down, so when the MainWindow is created, it throws an exception since the dispatcher-loop is already shut down.
- MainWindow is created. As above, it adds itself to Application.Current.Windows and sets itself as Application.Current.MainWindow.
- However, the condition for shutting down the application has already been reached. But, so far, the application had no chance to do something.
- Now Run() is called. The dispatcher-loop starts again and now has a chance to shutdown the application. So it shuts down the application and closes any open windows.
同样,没有 b。
因此,解决这一问题的一个途径是改变为公开出口。 然后,第4步就没有达到关闭的理由。 更好的(更像通常的WPF申请一样)是确定适当的申请。 将启动Uri从App.xaml移走,而是处理启动活动:
private void OnStartup(object sender, StartupEventArgs e)
{
this.ShutdownMode = ShutdownMode.OnExplicitShutdown;
new DialogWindow().ShowDialog();
var mainWindow = new MainWindow();
this.ShutdownMode = ShutdownMode.OnLastWindowClose; // or OnMainWindowClose
mainWindow.Show();
}
由于我们在关闭了方言窗口的同时,已开始实行直接关闭,因此没有理由申请开始关闭。 然后,在创立了MainWindow之后,我们又有一个窗口作为主要窗口和(其中一个)应用窗口。 因此,我们可以转向我们实际上想要的关闭模式,并展示主要窗口。