Startup
事件来做很多事情,比如初始化,创建多个表单,blablabla。
但是,尝试创建一个新的 WPF 应用程序并添加此事件处理程序:
private void App_Startup(object sender, StartupEventArgs e)
{
Window window = new Window();
}
关闭主窗口后,您的应用程序将挂起在内存中。此时在 VS 中暂停执行将会导致丑陋的 crash 调用堆栈窗口,其中有大量调用远离我的源代码。
有什么想法吗?
P.S.:我需要实例化所有窗口一次以用于自学配置目的。我应该使用其他地方吗?
让我举一个更好的例子(上面的例子很好地重现了问题,似乎很难理解我实际上在做什么)。我删除
StartupUri
然后:
private void App_Startup(object sender, StartupEventArgs e)
{
// un-comment this line to reproduce the problem:
// Window window = new Window();
// actual implementation will be
// Window1 window1 = new Window1();
// Window2 window2 = new Window2();
// Window3 window3 = new Window3();
// Window4 window4 = new Window4();
// ...
// start main window as usually
MainWindow mainWindow = new MainWindow();
mainWindow.Show();
}
为什么我需要窗口实例(window1、..2、..3、...)?因为将检查它们的内容以创建我想要保存配置的控件列表。其中一些窗口将“永远不会”显示给用户(例如,如果他不是管理员),其中一些是弹出窗口,一些是编辑器等。所以我不想显示它们。但在任何应用程序启动时,都必须创建并保存配置。我现在正在寻找这样做的地方。 令人惊讶的是,使用专用事件
Startup
似乎在创建多个窗口时存在一些
问题,但不显示它们。问题是为什么以及如何解决。 再进行一些测试。尝试这段代码并解释一下,为什么应用程序关闭而不显示
窗口?
private void App_Startup(object sender, StartupEventArgs e)
{
Window window = new Window();
window.Close(); // closing without opening window
MainWindow mainWindow = new MainWindow();
mainWindow.Show();
//mainWindow = new MainWindow(); // can be un-commented, for absolutely no effect
mainWindow.Show();
mainWindow.Show();
mainWindow.Show();
mainWindow.Show(); // you will not see mainWindow at all, all Show doing nothing
}
更多问题。我该怎么办?
一些有用但有气味的东西:
private void App_Startup(object sender, StartupEventArgs e)
{
Window window = new Window();
MainWindow mainWindow = new MainWindow();
mainWindow.ShowDialog();
Shutdown();
}
注意,调用
ShowDialog
(这将使事件处理程序等待该窗口关闭)并立即调用
Shutdown
。目前还不清楚
Startup
事件处理程序创建某些窗口实例时出现的问题是什么。有什么想法吗?
StartupUri
中指定的窗口只会在启动事件之后立即创建。默认情况下,必须关闭主窗口才能关闭应用程序。由于它从未显示,用户没有机会执行此操作,并且应用程序似乎永远挂起。当执行暂停时,您看到的是正常的消息循环,这里没有崩溃。添加
window.Show()
以查看真正的“主”窗口。如果您决定手动实例化主窗口,请从
StartupUri
中删除
App.xaml
属性。或者,在主窗口中的 Loaded
事件被触发后,保留该属性并实例化其他窗口。winforms
- 在
Main
中做所有事情。然而,这在 wpf 中有点棘手从
StartupUri
App.xaml
;将 App.xaml
Build Action
设置为 Page
(这听起来很奇怪,但它适用于桌面应用程序)。这将从自动生成的类中删除 Main
方法(App.g.cs和 App.g.i.cs)。 将
Main
Application
:
public partial class App : Application
{
[STAThread]
public static void Main()
{
Window window1 = new Window();
Window window2 = new Window();
Window window3 = new Window();
// ...
MainWindow start = new MainWindow();
start.ShowDialog();
SomeOtherWindow next = new MainWindow();
next.ShowDialog();
}
}
现在我可以直接控制显示哪个窗口以及何时显示(程序流程控制),并且在创建窗口实例而不显示它们时不再存在未关闭应用程序的bug
。 可疑的事情是这个
Page
设置和事实,我没有实例化
Application
,也没有调用Run()
。我还不知道,这是否会成为未来的问题。如果能确定的话就很高兴了。可能仍然需要初始化应用程序(以加载资源?),然后
[STAThread]
public static void Main()
{
App app = new App();
app.InitializeComponents();
// ... the rest
// possibly app.MainWindow = start; or app.MainWindow = next;
// if only 1 window, then app.Run(new MainWindow());
}
ShutdownMode = ShutdownMode.OnMainWindowClose;
可以通过
OnStartup
的
App.xaml.cs
方法进行设置
这样,即使您打开了其他一些窗口,整个应用程序也会关闭。