当从控制台应用程序运行WPF应用程序时,将忽略App.xaml。

4
假设我使用Visual Studio 2019中的默认模板创建了一个WPF应用程序,我们将其称为TestApplication,即我已经设置好了App.xaml、App.xaml.cs、MainWindow.xaml和MainWindow.xaml.cs。现在我想从另一个程序集的控制台应用程序中以编程方式运行这个WPF应用程序。
[STAThread]
static void Main(string[] args)
{
    var app = new TestApplication.App();
    app.Run();
}

现在,仅凭这个代码是无法正常工作的。这个答案的第一部分提供了一种替代方法:如果我将app.Run()更改为app.Run(new TestApplication.MainWindow()),那么实际上打开的是MainWindow

然而,这看起来应该是必要的:默认情况下,App.xaml 在其定义<Application />中包括了StartupUri="MainWindow.xaml",这表明它应该可以自行找到MainWindow

更普遍的情况是,通过这种方法完全忽略了App.xaml;在我的设置中,我已经在App.xaml中包含了一个ResourceDictionary集合,但它们根本不会被加载。

所以,有没有一种以编程方式运行WPF应用程序并考虑XAML内容的方法呢?

编辑:在尝试一番后,我意识到InitializeComponent负责处理窗口和用户控件的这一点。如这个答案所建议的,将上面的代码更改为

[STAThread]
static void Main(string[] args)
{
    var app = new TestApplication.App();
    app.InitializeComponent();
    app.Run();
}

确实使我更进一步,但是我却遇到了一个

System.IO.IOException: '找不到资源'mainwindow.xaml'.'

我想这可能是因为相对路径在不同的程序集中无法正确解析,但它并没有提供太多关于如何解决问题的提示。


1
@EdPlunkett:我只是想说当一个窗口实际上被打开了。 - fuglede
1个回答

2

看起来手动覆盖Application.StartupUri也是足够的,具体操作如下:

最初的回答

[STAThread]
static void Main(string[] args)
{
    var app = new TestApplication.App();
    app.InitializeComponent();
    app.StartupUri = new Uri($"pack://application:,,,/TestApplication;component/{app.StartupUri}");
    app.Run();
}

虽然这不是最令人满意的解决方案,但它似乎可以胜任工作,因为在App.xaml中的所有其他相对路径都按预期进行了转换;特别是,如果我在App.xaml中包含一个SourceStyle.xamlResourceDictionary,那么控制台应用程序也会正确地获取到它。"最初的回答"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接