i have a problem with Resource dictionaries and mergeddictionaries in general, especially when it comes to resource-lookup performance. After some performance testing i found that ResourceDictionary.get_MergedDictionaries is the call with the most hits (checked in ANTS profiler). We have around ~300 resource dictionary xamls, and a lot of them are using merged dictionary to "include" other styles. Well the get_MergedDictionaries count on one part of our application, where not much is happening, was around 10 million hits. So my guess is we are doing something completely wrong with Resource dictionaries in general. So i tried to refactor everything and i want to try to get rid of all the merged dictionaries.
Now to the actual question. I tried to get rid of the mergeddictionaries but i failed. My understanding is that when you use StaticResource the lookup needs the resource to be defined before the current one. I made the following short example:
One main project and one custom control library.
the custom control library contains 2 xamls.
<!-- Colors.xaml -->
<ResourceDictionary [stripped namespaces] >
<SolidColorBrush x:Key="myColor" Color="Green"/>
</ResourceDictionary>
<!-- Templates.xaml -->
<ResourceDictionary [stripped namespaces]>
<ControlTemplate x:Key="myTemplate" TargetType="Button">
<Rectangle Fill="{StaticResource myColor}"/>
</ControlTemplate>
</ResourceDictionary>
Now in the main project, the MainWindow.xaml looks like this
<Window x:Class="ResourceTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ResourceTestLib;component/Themes/Colors.xaml"/>
<ResourceDictionary Source="/ResourceTestLib;component/Themes/Template.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Button Template="{StaticResource myTemplate}"/>
</Grid>
</Window>
That is the desired goal. but unfortunately this crashes because the resource "myColor" cannot be found. I of course know how to fix it, add a mergeddictionary in Templates.xaml and reference Colors.xaml but i always thought, well i never really checked, that resources are looked up depending on the logical tree and the resources of the element. My understanding is; Button is created; try to lookup template .. found; try to lookup color, not found on own resources, walk up and use the windows resources.
It seems that i'm wrong. So i hope someone can shed some light on this for me. We make heavy use of WPF and despite of this we accomplished a lot with it, but because of some wrong learned behaviour in the beginning, our performance is pretty bad just because of the resource lookup. Any help would be greatly appreciated
Thanks in advance Best regards Nico
DynamicResource
instead ofStaticResource
for MyColor? Last I checked, the performance difference was not enough to justify not using Dynamic Resources. – PelagColors.xaml
orTemplates.xaml
in your entire application. Usually I load generic resources (colors, templates, styles, etc) intoApplication.Resources
, than specific resources like DataTemplates are loaded into the UserControl that uses them. – Pelag