Merging Resource Dictionaries for fun and profit

Here are two scenarios where merged ResourceDictionary objects are the way forward.

I’m working on a WPF project that needs to be single instance. Heaven forbid that the WPF team should pollute the purity of their framework with support for this kind of thing (or NotifyIcon support but that’s another story) so I’m using the code recommended by Arik Poznanski: WPF Single Instance Application. I like this because it both enforces a single instance and provides an interface that reports the command line passed to any attempt to launch another instance.

An issue with using this code is that you need to write a Main function and so App.xaml is set to Page instead of Application Definition. Once you’ve done this the program works fine but the Visual Studio designer fails to load resources in UserControls (and in Windows containing those UserControls).

The fix is to factor all of the application level resources out into a separate ResourceDictionary (i.e. MergedResources.xaml). Once you’ve done this merge the new ResourceDictionary into App.xaml as follows:


<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="MasterResources.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

Next, in each Window or UserControl reference the same ResourceDictionary:


<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="MasterResources.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

The designer will now be able to find the correct resources for each UserControl and Window.

The second scenario is factoring resources and other Xaml into a DLL. To pull resources in from a referenced assembly you just need to use a Pack Uri when merging in the remote ResourceDictionary:


<ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/MyDll;component/ExternalResources.xaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

If you’re putting Windows and UserControls in the DLL use exactly the same approach to reference the resources using ResourceDictionary.MergedDictionaries and you’ll get designer support for these as well.

Comments

Priyagl0101



where should the code <resourcedictionary>    <resourcedictionary.mergeddictionaries>        <resourcedictionary source="/MyDll;component/ExternalResources.xaml">    </resourcedictionary></resourcedictionary.mergeddictionaries></resourcedictionary>

be included I mean in which file ? as we don't want to change anything in the parent project, so where should these lines be written?

June 28, 2012

Rob Ellison



It has to be added where you're using the resource dictionary. So if you've factored resources out into a DLL you'll have to change the project that uses the DLL to reference it. Not sure what you mean by not changing the parent project.

June 28, 2012

I Thought He Came With You
Robert Ellison's blog.

Elsie Street, west slope of Bernal Heights

Like Debate is an experiment in civilized online debate. Try a test debate or weigh in on the fate of the Oxford comma.

Blog Archives