背景:我正在使用MVVM创建一个WPF应用程序,并使用DI容器来构建我的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中挂钩MainWindow
来创建OnStartup
,如下所示:
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();
然而,这是一个丑陋的黑客,如果我想稍后在app.xaml文件中添加其他内容,则无法帮助我: - (
我应该挂钩其他活动吗?有办法解决这个问题吗?
答案 0 :(得分:45)
不要覆盖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 :(得分:22)
最简单的解决方法是定义 x:名称:
<Application x:Name="App" ...
<Application.Resources>
...
</Application.Resources>
</Application>
答案 2 :(得分:13)
我遇到过类似/同样的问题。有一个VS代码生成错误,当<Application.Resources>
只包含一个条目且没有<Application.Resources>
属性时,有时不会插入将StartupUri
连接到程序其余部分所需的代码。< / p>
详细说明: http://bengribaudo.com/blog/2010/08/19/106/bug-single-application-resources-entry-ignored (免责声明 - 链接指向我的博客)
答案 3 :(得分:2)
要解决这个已知错误,您还可以通过编程方式添加资源。
var rd = new ResourceDictionary()
rd.Source = new Uri("pack://application:,,,/Resources;component/Colors.xaml");
Resources.MergedDictionaries.Add(rd);
此代码可以放在App
类的构造者中。