During development of my UWP app I have noticed and intersting oddity which I have hard time explaining.
I user MvvmLight and I decided to add the ViewModelLocator resource instance in a separate ResourceDictionary Core.xaml which will be referenced from MergedDictionaries
in App.xaml.
Following is the content of App.xaml:
<Application ...>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Core.xaml" />
<ResourceDictionary Source="Resources/Converters.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Contents of Core.xaml:
<ResourceDictionary ...>
<viewModel:ViewModelLocator x:Key="Locator" />
</ResourceDictionary>
Now I supposed the resources in Core.xaml are initialized during the InitializeComponent
method call in App.xaml.cs, but when I tried to use the ServiceLocator
class (which is set in the constructor of ViewModelLocator in MvvmLight) - like this - ServiceLocator.Current.GetInstance<INavigationService>().Navigate<MainViewModel>();
- I get an exception saying:
An exception of type 'System.InvalidOperationException' occurred in
Microsoft.Practices.ServiceLocation.dll but was not handled in user code
Additional information: ServiceLocationProvider must be set.
Indeed, if I put an breakpoint in the constructor of ViewModelLocator, it is not called before the Window is activated. More interestingly still - if I manually reference the Locator resource key (for example putting Debug.WriteLine(Resources["Locator"]);
above the call of ServiceLocator
), everything works fine. The same goes if I move the ViewModelLocator
resource directly to App.xaml - then it is instantiated during IntializeComponent
.
Is there a lazy instantiation of merged resource dictionaries in UWP apps? Or why does it behave this way?
A ResourceDictionary
in UWP doesn't have any code behind (no InitializeComponent
). Therefore, any class references defined in a ResourceDictionary
won't be initialized directly.
Neither does the App.InitializeComponent
do this for you. Resource dictionaries in UWP just don't provide this functionallity - don't ask me why.
You can easily try this by trying to initialize a DataTemplate
in a ResourceDictionary
.
This should - sadly - neither work.
However, using the Resources["Locator"]
access in code behind triggers the constructor of the class and you're fine.
This ain't be a solution, but a explanation of your problem. I hope it helps you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With