我正在尝试运行一个窗口,关闭它,然后以类似于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>
但我仍然得到例外。
答案 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()
方法,这是自动完成的。