如果我的应用程序没有设置StartupUri,App.xaml文件将不会被解析吗?

47

背景:我正在使用MVVM创建一个WPF应用程序,并使用依赖注入容器构建我的ViewModels

我的App.xaml看起来像这样:

<Application x:Class="WpfApp.App"
    ...xmlns etc...
    StartupUri="MainWindow.xaml">
    <Application.Resources>
        <app:ServiceLocator x:Key="serviceLocator" />
    </Application.Resources>
</Application>

MainWindow.xaml长这样:

<Window x:Class="CompositeMefWpfApp.MainWindow"
    ...xmlns etc... >
    <Control.DataContext>
        <Binding Path="MainWindowViewModel" Source="{StaticResource serviceLocator}" />
    </Control.DataContext>

现在,所有东西都很好,但是StartupUri硬编码到了XAML中,我不想这样做。
根据我找到的一些博客文章的指导,我删除了StartupUri,并尝试通过在App.xaml.cs中连接OnStartup来创建MainWindow,就像这样:

protected override void OnStartup( StartupEventArgs e )
{
    base.OnStartup(e);
    new MainWindow().Show();
}

问题在于当尝试显示窗口时,应用程序会崩溃,并出现以下异常:

找不到名为“{serviceLocator}”的资源。资源名称区分大小写。 在标记文件“WpfApp;component/mainwindow.xaml”的对象“System.Windows.Data.Binding”处发生错误,第8行第45个位置。

据我所知,<Application.Resources> 部分根本没有从 xaml 文件中读取。 我可以在 OnStartup 中放一些代码来以编程方式添加资源,如下所示:

Resources.BeginInit();
Resources.Add("serviceLocator", new ServiceLocator());
Resources.EndInit();

然而,这是一个丑陋的hack,如果我想以后在app.xaml文件中放置其他东西,它对我没有帮助:-(

我应该挂钩其他事件吗?有什么解决方法吗?

4个回答

55

不要重写 OnStartup,尝试使用事件替代:

<Application x:Class="My.App"
    xmlns="..."
    Startup="Application_Startup"
    ShutdownMode="OnExplicitShutdown">
        <Application.Resources>
            <app:ServiceLocator x:Key="serviceLocator" />
        </Application.Resources>
    </Application>

后台代码:

public partial class App : Application
{
    public App()
    { }
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        // TODO: Parse commandline arguments and other startup work 
        new MainWindow().Show();
    }
}

1
为什么从XAML设置事件很重要?如果从构造函数中设置,它会失败... - Mikhail Orlov
1
请注意,PRISM应用程序默认存在此问题。通过添加空事件Application_Startup解决。 - Karel Kral

26

链接已经失效。甚至无法通过搜索找到问题。 - Ilya Serbis
新增了一个:https://connect.microsoft.com/VisualStudio/feedback/details/772087/ - Ilya Serbis
这个解决方案对我很有效,而且它是最简单的。 - bignermo
这对我帮助很大。谢谢 :) - karollo
3
两个链接都失效了。 - Rye bread

13

Visual Studio 2015仍然存在这个bug :-( 又浪费了我三个小时的时间。 - Philip Kendall
1
这个错误有时会在我在VS 2017中开发的应用程序的生产环境中发生。因此,看来这个漏洞仍然存在。 - Rye bread
2020年末,问题仍然存在。在<Application ...>上使用一个空的Startup="Application_Startup"事件处理程序对我很有帮助。虽然感觉有点笨重。 - naskew

2
为了解决这个已知的 bug,您也可以通过编程方式添加资源。
var rd = new ResourceDictionary()
rd.Source = new Uri("pack://application:,,,/Resources;component/Colors.xaml");
Resources.MergedDictionaries.Add(rd);

这段代码可以放在App类的构造函数中。


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