在WPF中多次调用Application.Run

时间:2011-05-07 20:25:58

标签: c# wpf

我正在尝试运行一个窗口,关闭它,然后以类似于Windows窗体的方式运行第二个窗口。

namespace WpfApplication1
{

public partial class App : Application
{
    [STAThread]
    public static void Main()
    {
        Application app = new Application();
        //windowMain.Show();
        app.ShutdownMode = ShutdownMode.OnExplicitShutdown;
        MainWindow windowMain = new MainWindow();
        app.Run(windowMain);
        Window1 window1 = new Window1();
        window1.Show();
        app.Run(window1);
    }
}
}

我已将App.xaml属性中的Build Action从ApplicationDefinition设置为Page,但是当window1初始化时,程序会抛出异常。我做错了什么?

编辑:我已按照第一个回答的建议修改了App.xaml中的xaml,并按照评论的建议编辑了主要内容。

<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
ShutdownMode="OnExplicitShutdown">
<Application.Resources>
</Application.Resources>
</Application>

但我仍然得到例外。

3 个答案:

答案 0 :(得分:8)

我认为当您关闭第一个窗口时,您的应用程序正在关闭。您需要将Application.ShutdownMode设置为OnExplicitShutdown。

答案 1 :(得分:7)

好的,这就是我到目前为止所做的。 Solution Builder查找Main()函数。为什么它不是WinMain()函数我仍然没有百分百清楚。如果没有Main(),则会出错。只要项目属性:“应用程序”页面/选项卡:属性:“StartUp Object”设置为指向main()之一,您可以拥有多个Main()。这是通过自动创建的下拉列表完成的。

创建“WPF应用程序”项目时,Visual Studio(VS)会创建一个名为“App.xaml”的xaml文件。这是一个类声明,其中“App”派生自“Application”类。 VS还会自动为xaml文件生成隐藏文件。创建xaml文件时,它会创建一个“name.g.i.cs”文件。它在创建xaml文件后第一次构建项目时创建“name.g.cs”文件。在这种情况下,它会创建“App.g.cs”和“App.g.i.cs”。默认情况下隐藏这些文件。要查看它们,请按解决方案资源管理器顶部的“显示所有文件”按钮,它们位于“\ obj \ 86 \ Debug”文件夹中。删除xaml文件时,“name.g.i.cs”和“name.g.cs”文件仍然保留,不会被删除。

由VS创建时,“App.xaml”文件的“构建操作”属性设置为“应用程序定义”。当此属性设置为“应用程序定义”时,将在“name.g.i.cs”中自动创建Main()函数:

    [System.STAThreadAttribute()]
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static void Main()
{
    WpfApplication8.App app = new WpfApplication8.App();
    app.InitializeComponent();
    app.Run();
}

当此属性设置为“Page”时,VS会自动删除Main()函数。您可以在代码或xaml中创建新的“Application”派生类。我还没有找到一个简洁的方法在xaml中做到这一点。似乎没有xaml“Application”派生类的模板。我创建了一个“.cs”代码文件,然后将其重命名为.xaml文件。出于某种原因,VS不允许您将多个xaml“应用程序”声明文件设置为“应用程序构建”,它甚至不允许您在“项目:属性:应用程序”中选择一个:“启动对象“属性。

正如您在隐藏的Main()中看到的,实例化并运行“App”的实例。如果使用自己的Main()函数:可以声明并运行基本“Application”类或“Application”派生类(无论是在代码中还是在xaml中声明)的实例。 “Application”类只应实例化一次,并且只能运行一次。如果在xaml中声明了“Application”派生类,则可以使用xaml文件中的StartUpUri属性运行一个简单的应用程序:StartupUri =“Windowname.xaml”。或者,顶级UI程序逻辑可以放在Startup事件处理程序中。如果“Startup =”Application_Startup“放在”App.xaml“文件中,则可以写入事件处理程序:

private void Application_Startup(object sender, StartupEventArgs e)
{
    MainWindow windowMain = new MainWindow();
    windowMain.ShowDialog();
    Window1 window1 = new Window1();
    window1.ShowDialog();
    Shutdown();
}

你必须在这里使用ShowDialog(),因为它会一直阻塞,直到窗口关闭。如果您使用Show(),它将显示一个窗口,然后立即显示另一个窗口并关闭应用程序。在这种情况下,不需要自己调用Run()方法,这是自动完成的。 无论是在代码中还是在xaml中声明,“Application”类实例都可以在代码中运行。然后,您可以在调用Run()之前执行初始化代码。这将使用另一种方式放在Application_Startup()事件处理程序中。但是,如果在程序中进行“Application.Run”调用,则不应在Main()或Application Class外部的任何位置或在调用的事件和函数中打开窗口(使用show()或ShowDialog())来自那些在“Application.Run()”期间调用的事件。

Application类具有ShutdownMode属性(Application.ShutdownMode)。默认值为:“OnMainWindowClose”。此属性也可以在代码或xaml中设置为“OnLastWindowClose”或“OnExplicitShutdown”。如果您不希望程序在MainWindow关闭时关闭,则需要重置此项。

我认为,出于我的目的,最好不要使用Application类,只需使用Show()和“ShowDialog()”调用windows。这样我可以使用WPF页面,但我也可以调用Windows Forms或DirectX屏幕,只要它们不是同时打开,或者根本没有UI,如果程序是远程运行的话。有没有理由不这样做?

答案 2 :(得分:2)

如果您要做的只是显示一个窗口,当它关闭时,显示另一个窗口,当关闭时关闭整个应用程序,您应该将Build操作保持为ApplicationDefinition,将ShutdownMode设置为{{1 (可能在OnExplicitShutdown中,但你也可以在代码隐藏中)并将以下代码放在应用程序的App.xaml事件的事件处理程序中:

Startup

你必须在这里使用private void Application_Startup(object sender, StartupEventArgs e) { MainWindow windowMain = new MainWindow(); windowMain.ShowDialog(); Window1 window1 = new Window1(); window1.ShowDialog(); Shutdown(); } ,因为它会在窗口关闭之前阻塞。如果你使用了ShowDialog(),它会显示一个窗口,然后立即显示另一个窗口并关闭应用程序。

不需要自己运行Show()方法,这是自动完成的。