替换WPF入口点

时间:2011-05-27 18:56:21

标签: .net wpf entry-point

WPF定义了自己的Main()方法。我应该如何用我自己的Main方法替换它(通常)打开WPF MainWindow(例如通过命令行参数添加非WPF脚本模式)?

5 个答案:

答案 0 :(得分:51)

一些示例描述了将App.xaml的构建操作从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视图(MV-VM)未在设计时解析App.xaml中保存的资源。

答案 1 :(得分:20)

通常我会修改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();
    }
}

答案 2 :(得分:16)

人 问题是你的程序有两个静态Main()方法,这会导致编译器之间抱怨;要解决此问题,请尝试以下方法之一:

  • 告诉编译器您的静态Main()方法应该是执行入口点 - 将项目的“Startup object”设置设置为包含静态Main()方法的类(在Solution Explorer中右键单击项目,选择“属性”,然后在“应用程序”选项卡下查找“启动对象”设置。
  • 关闭App.g.cs静态Main()方法的自动生成 - 在Solution Explorer中,右键单击App.xaml,选择“Properties”,然后将“Build Action”从“ApplicationDefinition”更改为“Page ”

答案 3 :(得分:4)

使用自定义静态Main方法创建新类。在此方法结束时,只需调用WPF生成的原始App.Main():

public class Program
{
    [STAThread]
    public static void Main(string[] args)
    {
        // Your initialization code
        App.Main();
    }
}

然后将项目的“启动对象”设置设置为包含静态Main()的类。

答案 4 :(得分:0)

使用自定义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");
...
}