【发布时间】:2011-09-03 15:13:33
【问题描述】:
WPF 定义了自己的Main() 方法。我应该如何用我自己的 Main 方法替换它,该方法(通常)打开 WPF MainWindow(例如,通过命令行参数添加非 WPF 脚本模式)?
【问题讨论】:
标签: .net wpf entry-point
WPF 定义了自己的Main() 方法。我应该如何用我自己的 Main 方法替换它,该方法(通常)打开 WPF MainWindow(例如,通过命令行参数添加非 WPF 脚本模式)?
【问题讨论】:
标签: .net wpf entry-point
一些示例描述了将 App.xaml 的构建操作从 ApplicationDefinition 更改为 Page 并编写自己的 Main() 来实例化 App 类并调用其 Run() 方法,但这可能会在App.xaml 中应用程序范围资源的解析。
相反,我建议在自己的类中创建自己的Main(),并在项目属性中将启动对象设置为该类:
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 中保存的资源。
【讨论】:
Main()只是实例化App并调用Run()。 Startup 事件在System.Windows.Application 的构造函数中触发。 Run() 附加 Dispatcher 并开始消息泵。 InitializeComponent() 应该在 Apps 的构造函数中调用。不是吗?
App 并在那里调用InitializeComponent() 以避免App.Main()。为简洁起见,其余部分我过于简化了。 Startup 被Application.OnStartup() 触发,只有派生的App 类的构造函数可以在触发之前订阅Startup。这是因为Application 的构造函数异步调用了一个调用OnStartup() 的方法,所以它实际上是在基构造函数和派生构造函数完成后运行的。
App.Main(),您只需添加它并将其设置为项目的入口点,然后直接调用App.Main()。
通常我会编辑 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.* 输出。
伙计们 问题是你的程序有两个静态 Main() 方法,这会导致编译器抱怨;要解决此问题,请尝试以下方法之一:
【讨论】:
使用您的自定义静态 Main 方法创建新类。在这个方法的最后,只需调用 WPF 生成的原始 App.Main():
public class Program
{
[STAThread]
public static void Main(string[] args)
{
// Your initialization code
App.Main();
}
}
然后将项目的“启动对象”设置为包含静态 Main() 的类。
【讨论】:
使用自定义 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");
...
}
【讨论】: