App.xaml file does not get parsed if my app does not set a StartupUri?
resources, startup, wpf, xaml
Solution
Rather than overriding OnStartup, try using an event instead:
<Application x:Class="My.App"
xmlns="..."
Startup="Application_Startup"
ShutdownMode="OnExplicitShutdown">
<Application.Resources>
<app:ServiceLocator x:Key="serviceLocator" />
</Application.Resources>
</Application>
Code behind:
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();
}
}
Problem
Background: I'm creating a WPF app using MVVM, and using a DI container to build my ViewModels My App.xaml looks like this: ``` <Application x:Class="WpfApp.App" ...xmlns etc... StartupUri="MainWindow.xaml"> <Application.Resources> <app:ServiceLocator x:Key="serviceLocator" /> </Application.Resources> </Application> ``` MainWindow.xaml looks like this: ``` <Window x:Class="CompositeMefWpfApp.MainWindow" ...xmlns etc... > <Control.DataContext> <Binding Path="MainWindowViewModel" Source="{StaticResource serviceLocator}" /> </Control.DataContext> ``` Now, this all works fine, but the `StartupUri` is hardcoded into the XAML, which I don't want. Following guidance of several blogposts and articles I found, I removed the `StartupUri`, and tried to create the `MainWindow` by hooking `OnStartup` in App.xaml.cs, like this: ``` protected override void OnStartup( StartupEventArgs e ) { base.OnStartup(e); new MainWindow().Show(); } ``` The problem is, the app crashes when trying to show the window, with this exception: Cannot find resource named '{serviceLocator}'. Resource names are case sensitive. Error at object 'System.Windows.Data.Binding' in markup file 'WpfApp;component/mainwindow.xaml' Line 8 Position 45. As far as I can tell, the `<Application.Resources>` section is simply not being read out of the xaml file. I can put some code in the OnStartup to add the resource programatically like this: ``` Resources.BeginInit(); Resources.Add("serviceLocator", new ServiceLocator()); Resources.EndInit(); ``` However that's an ugly hack, and doesn't help me if I wanted to put something else in the app.xaml file later on :-( Should I be hooking some other event? Is there a way around this?