With WPF applications where the resources should not be locally with the application but shared with multiple applications, the WPF resources can be added to a library. Using the MergedDictionaries property of a ResourceDictionary the resources from another assembly can be referenced, for global resources this is usually done within the App.xaml file. Having a Windows Forms host that makes use of WPF controls it’s also possible to use shared resources for WPF styling. This blog post shows how this can be done.
Having resources in a shared library (the sample has the library named WpfStylesLib), shared resources (Dictionary1.xaml), with a WPF application the resources can be made available application-wide by adding the resource dictionary to the MergedDictionaries in the file App.xaml. To reference the shared library I’m using the relative Pack URI syntax. Following the / is the name of the assembly: WpfStylesLib. ;component following the assembly name means the assembly is referenced from the local assembly. Dictionary1.xaml is the resource name in the referenced assembly. Now all the resources defined within this dictionary can be used from the WPF application.
<Application x:Class="WPFResourceTest.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="/WpfStylesLib;component/Dictionary1.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
With a Windows Forms host usually there’s no App.xaml. It’s easy to add the resources from a shared library programmatically. Within the Main method of Program.cs I’m creating a WPF Application instance. To not get in conflict with the Windows Forms Application class I’ve added a namespace alias named WPF to System.Windows. After a new Application instance is created, Application.Current is set. Similar to the XAML code before I’m using the Resources property of the Application, reference the MergedDictionaries, and add a ResourceDictionary to it. Here I’m using the absolute Pack URL syntax to reference the resources in the shared assembly.
WPF.Application app = new WPF.Application(); WPF.ResourceDictionary dict = new WPF.ResourceDictionary(); dict.Source = new Uri("pack://application:,,,/StylesLib;component/Dictionary1.xaml"); WPF.Application.Current.Resources.MergedDictionaries.Add(dict);
More information on WPF and Windows Forms interop in my WPF workshop