Unified ResourceDictionary Initialization in a UWP Application

During the development of my application for UWP, I noticed and became interested in a strange thing, which is difficult for me to explain.

I am a MvvmLight user, and I decided to add an instance of the ViewModelLocator resource to a separate ResourceDictionary Core.xaml, which will be referenced by MergedDictionaries in App.xaml. The following is the contents 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> 

Core.xaml Content:

 <ResourceDictionary ...> <viewModel:ViewModelLocator x:Key="Locator" /> </ResourceDictionary> 

Now I assumed that resources in Core.xaml are initialized when I call the InitializeComponent method in App.xaml.cs, but when I tried to use the ServiceLocator class (which is set in the ViewModelLocator constructor in MvvmLight) - like this - ServiceLocator.Current.GetInstance<INavigationService>().Navigate<MainViewModel>(); - I get an exception:

 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. 

In fact, if I set a breakpoint in the ViewModelLocator constructor, it is not called before the window is activated. Even more interesting: if I manually refer to the Locator resource key (for example, by placing Debug.WriteLine(Resources["Locator"]); on a call to ServiceLocator ), everything works fine. The same thing happens if I move the ViewModelLocator resource directly to App.xaml - then it is created with IntializeComponent .

Is there lazy creation of unified resource dictionaries in UWP applications? Or why does he behave this way?

+5
source share
1 answer

A ResourceDictionary in UWP has no code (no InitializeComponent ). Therefore, any references to classes defined in the ResourceDictionary will not be initialized directly.

App.InitializeComponent does the App.InitializeComponent for you. Resource dictionaries in UWP just don't provide this feature - don't ask me why.

You can easily try this by trying to initialize a DataTemplate in a ResourceDictionary .
This should - unfortunately - not work.

However, using Resources["Locator"] accesses the code behind the triggers, the class constructor, and you're fine.

This is not a solution, but an explanation of your problem. Hope this helps you.

+6
source

Source: https://habr.com/ru/post/1238515/


All Articles