WPF定义了自己的Main()
方法。我该如何将其替换为我的Main
方法,以便(通常)打开WPF MainWindow
(例如,通过命令行参数添加非WPF脚本模式)?
WPF定义了自己的Main()
方法。我该如何将其替换为我的Main
方法,以便(通常)打开WPF MainWindow
(例如,通过命令行参数添加非WPF脚本模式)?
有些示例展示了将 App.xaml
的 Build Action 从 ApplicationDefinition
更改为Page
,并编写自己的 Main()
实例化 App
类并调用其 Run()
方法,但这可能会对 App.xaml 中应用程序范围资源的解析产生一些不必要的后果。
相反,我建议在其自己的类中创建您自己的 Main()
并将 Startup Object 设置为该类在项目属性中:
public class EntryPoint {
[STAThread]
public static void Main(string[] args) {
if (args != null && args.Length > 0) {
// ...
} else {
var app = new App();
app.InitializeComponent();
app.Run();
}
}
}
我这样做是为了利用一些必须在其他任何事情发生之前订阅的AppDomain
事件(例如AssemblyResolve
)。将App.xaml设置为Page
所带来的不良后果包括我在设计时使用的UserControl
视图(M-V-VM)无法解析在App.xaml中保存的资源。
通常我会编辑App.xaml
来添加此支持:
<Application x:Class="SomeNamespace.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup">
关键部分是我将StartupUri
更改为带有事件处理程序的Startup
,并在App.xaml.cs
中进行了更改。以下是一个例子:
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
int verbose = 0;
var optionSet = new OptionSet
{
{ "v|verbose", "verbose output, repeat for more verbosity.",
arg => verbose++ }
};
var extra = optionSet.Parse(e.Args);
var mainWindow = new MainWindow(verbose);
mainWindow.Show();
}
}
Console.*
输出。 - user7116大家好, 问题在于你的程序有两个静态的Main()方法,这会导致编译器出现错误提示;为了解决这个问题,请尝试以下建议:
创建一个包含自定义静态Main方法的新类。在该方法的结尾处,只需调用由WPF生成的原始App.Main()方法:
public class Program
{
[STAThread]
public static void Main(string[] args)
{
// Your initialization code
App.Main();
}
}
<ItemGroup>
<ApplicationDefinition Remove="App.xaml" />
<Page Include="App.xaml" />
</ItemGroup>
如果使用自定义的Main()方法,则可能会遇到问题,因为未设置StartupUri。
您可以在App类中使用以下代码轻松设置它(不要忘记从App.xaml中删除StartupUri并将其Build Action设置为Page):
[STAThread]
static void Main()
{
App app = new App();
app.InitializeComponent();
app.Run();
}
protected void OnStartup(object sender, StartupEventArgs e)
{
var toUri = new UriTypeConverter();
StartupUri = (Uri)toUri.ConvertFrom("MainWindow.xaml");
...
}
Main()
方法只是实例化了App
并调用了Run()
。System.Windows.Application
的构造函数会触发Startup
事件。Run()
方法附加了一个Dispatcher
并开始消息泵。InitializeComponent()
应该在App
的构造函数中被调用。是吗? - Joel B FantApp
中添加了一个构造函数,并在其中调用InitializeComponent()
,以避免使用App.Main()
。为了简洁起见,我将其余部分过度简化了。Startup
由Application.OnStartup()
触发,只有派生的App
类的构造函数可以在其触发之前订阅Startup
。这是因为Application
的构造函数异步调用一个方法来调用OnStartup()
,所以它实际上是在基类和派生类构造函数完成后运行的。 - Joel B FantApp.Main()
,而是添加以下代码并将其设置为项目的入口点,然后直接调用App.Main()
。 - Jason Goemaat