Application.Startup事件限制(bug?)

时间:2014-03-17 16:38:43

标签: c# wpf window

它说,我可以将Startup事件用于许多事情,比如初始化,创建多个表单,blablabla。

但是,尝试创建一个新的WPF应用程序并添加此事件处理程序:

    private void App_Startup(object sender, StartupEventArgs e)
    {
        Window window = new Window();
    }

关闭主窗口后,您的应用程序将挂起在内存中。在那一刻暂停在VS中执行将丢弃丑陋的 crash 调用堆栈窗口,其中有很多调用远离我的源代码。

有什么想法吗?

P.S。:我需要将所有窗口实例化为自学习配置目的一次。我应该使用其他地方吗?

Call stack


让我举一个更好的例子(上面的例子很好地重现了这个问题,似乎很难理解我实际上在做什么)。我删除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();
    }

为什么我需要windows实例(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事件处理程序中创建某些窗口实例的问题是什么。有什么想法吗?

2 个答案:

答案 0 :(得分:3)

通过执行此操作,您刚刚创建的窗口已成为主窗口:StartupUri中指定的窗口将仅在启动事件之后立即创建。默认情况下,必须关闭主窗口才能使应用程序关闭。由于它从未显示过,用户没有机会这样做,应用程序似乎永远挂起。暂停执行时您所看到的是正常的消息循环,此处没有崩溃。添加window.Show()即可查看您真实的'窗口。

如果您决定手动实例化主窗口,请从StartupUri中删除App.xaml属性。或者,保留属性并在主窗口发出Loaded事件后实例化其他窗口。

答案 1 :(得分:1)

我有解决方案,这对我来说似乎很好。 Idea与winforms类似 - 在Main中执行所有操作。

然而,这在wpf中有点棘手(我使用this问题作为指导):

  • 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 。< / p>

可疑事情是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());
    }