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?
Rather than overriding OnStartup, try using an event instead:
Code behind: