
{"id":1551,"date":"2014-11-24T18:36:04","date_gmt":"2014-11-24T23:36:04","guid":{"rendered":"http:\/\/www.ikriv.com\/blog\/?p=1551"},"modified":"2014-11-24T18:36:04","modified_gmt":"2014-11-24T23:36:04","slug":"wpf-user-controls-do-not-use-merged-dictionaries-for-shared-resources","status":"publish","type":"post","link":"https:\/\/ikriv.com\/blog\/?p=1551","title":{"rendered":"WPF user controls: do not use merged dictionaries for shared resources"},"content":{"rendered":"<p>Resource dictionaries in WPF are not shared, unless they are part of <code>App.xaml<\/code>. That is, if you have a user control that loads (and uses) some resource dictionary, new instance of the dictionary will be loaded for each instance of the user control. This can (and does) lead to increased loading time and memory footprint.<\/p>\n<p>I wrote a test application that demonstrates the problem. <a href=\"http:\/\/www.ikriv.com\/\/blog\/wp-content\/uploads\/2014\/11\/WpfDoubleResources.zip\">Source code<\/a> <a href=\"http:\/\/www.ikriv.com\/\/blog\/wp-content\/uploads\/2014\/11\/WpfDoubleResources.vsdx_.zip\">Visio diagrams<\/a><\/p>\n<p><!--more--><\/p>\n<p><a href=\"http:\/\/www.ikriv.com\/\/blog\/wp-content\/uploads\/2014\/11\/WpfDoubleResources.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.ikriv.com\/\/blog\/wp-content\/uploads\/2014\/11\/WpfDoubleResources.png\" alt=\"WpfDoubleResources\" width=\"656\" height=\"438\" class=\"alignright size-full wp-image-1554\" \/><\/a><\/p>\n<p>Main window has four user control objects: two of type <code>UserControl1<\/code> (red) and two of type <code>UserControl2<\/code> (yellow). I defined a class named <code>BigFatObject<\/code> that allocates 200MB of memory. As instances of the class are created, they get sequential numbers: #1, #2, etc. Each user control refers to one instance of <code>BigFatObject<\/code> from <code>App.xaml<\/code> and to another instance from <code>Dictionary1.xaml<\/code>. You can see that instance #1 from <code>App.xaml<\/code> is shared by all controls, but each control has its own instance from <code>Dictionary1.xaml<\/code> (#2, #3, #4, and #5 respectively).<\/p>\n<p>As a result, the application has 5 (five) 200MB objects, and its memory footprint is over 1GB in size. In our production code private dictionaries contained not one big object, but lots of small objects (brushes, colors, styles, etc.). This affected not only memory footprint, but also the startup time. Each time a user control was created, the dictionary had to be processed and all objects in it re-created.<\/p>\n<p>Here&#8217;s how I use a resource dictionary in my user controls:<\/p>\n<pre>&lt;UserControl ...&gt;\n    &lt;UserControl.Resources&gt;\n        &lt;ResourceDictionary&gt;\n            &lt;ResourceDictionary.MergedDictionaries&gt;\n                &lt;ResourceDictionary Source=\"Dictionary1.xaml\"\/&gt;\n            &lt;\/ResourceDictionary.MergedDictionaries&gt;\n        &lt;\/ResourceDictionary&gt;\n    &lt;\/UserControl.Resources&gt;\n&lt;\/UserControl&gt;<\/pre>\n<p>Here&#8217;s the relationship between XAML files in the application:<\/p>\n<p><a href=\"http:\/\/www.ikriv.com\/\/blog\/wp-content\/uploads\/2014\/11\/WpfDoubleResXamls.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.ikriv.com\/\/blog\/wp-content\/uploads\/2014\/11\/WpfDoubleResXamls.png\" alt=\"WpfDoubleResXamls\" width=\"611\" height=\"636\" class=\"alignright size-full wp-image-1552\" \/><\/a><\/p>\n<p>And here&#8217;s the object graph:<\/p>\n<p><a href=\"http:\/\/www.ikriv.com\/\/blog\/wp-content\/uploads\/2014\/11\/WpfDoubleResObjects.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.ikriv.com\/\/blog\/wp-content\/uploads\/2014\/11\/WpfDoubleResObjects.png\" alt=\"WpfDoubleResObjects\" width=\"849\" height=\"625\" class=\"alignright size-full wp-image-1553\" \/><\/a><\/p>\n<p>You can easily observe the duplication.<\/p>\n<p>The solution to this problem is to put shared resource in <code>App.xaml<\/code> or include your dictionary from <code>App.xaml<\/code>. If you don&#8217;t have control over <code>App.xaml<\/code>, manually load your shared resources in code as described <a href=\"http:\/\/stackoverflow.com\/questions\/9739032\/set-up-application-resources-from-code\">in this StackOverflow article<\/a>. If you continue to refer to shared resources from user controls, you will suffer from increased memory footprint and slow load times.<br \/>\n<a style=\"display:none\" href=\"http:\/\/www.codeproject.com\/script\/Articles\/BlogFeedList.aspx?amid=1181663\" rel=\"tag\">CodeProject<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Resource dictionaries in WPF are not shared, unless they are part of App.xaml. That is, if you have a user control that loads (and uses) some resource dictionary, new instance <a href=\"https:\/\/ikriv.com\/blog\/?p=1551\" class=\"more-link\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[16,12],"tags":[],"class_list":["entry","author-ikriv","has-more-link","post-1551","post","type-post","status-publish","format-standard","category-demos","category-wpf"],"_links":{"self":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1551","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1551"}],"version-history":[{"count":0,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1551\/revisions"}],"wp:attachment":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1551"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1551"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1551"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}