ResourceDictionary in a separate assembly

Viewed 149718

I have resource dictionary files (MenuTemplate.xaml, ButtonTemplate.xaml, etc) that I want to use in multiple separate applications. I could add them to the applications' assemblies, but it's better if I compile these resources in one single assembly and have my applications reference it, right?

After the resource assembly is built, how can I reference it in the App.xaml of my applications? Currently I use ResourceDictionary.MergedDictionaries to merge the individual dictionary files. If I have them in an assembly, how can I reference them in xaml?

7 Answers

Check out the pack URI syntax. You want something like this:

<ResourceDictionary Source="pack://application:,,,/YourAssembly;component/Subfolder/YourResourceFile.xaml"/>

I know I will probably go to WPF hell but I like to keep it simple.

In my "external" WPF project named MyCorp.Wpf.Dll where I have a folder called assets with my resource dictionaries

MyCorp.Wpf.Dll
|- Assets
   |- TextStyles.xaml
   |- Colours.axml

Let's assume I have this TextStyles.xaml with the UI font styles that I need to apply because I need windows 10/ 11 style compliance

    <Style x:Key="Header" TargetType="TextBlock">
        <Setter Property="FontFamily" Value="Sego UI Light"/>
        <Setter Property="FontSize" Value="46" />
    </Style>
    
    <Style x:Key="Subheader" TargetType="TextBlock">
        <Setter Property="FontFamily" Value="Sego UI Light"/>
        <Setter Property="FontSize" Value="32" />
    </Style>
    <Style x:Key="Title" TargetType="TextBlock">
        <Setter Property="FontFamily" Value="Sego UI SemiLight"/>
        <Setter Property="FontSize" Value="24" />
    </Style>
    <Style x:Key="SubTitle" TargetType="TextBlock">
        <Setter Property="FontFamily" Value="Sego UI Normal"/>
        <Setter Property="FontSize" Value="20" />
    </Style>
    
    <Style x:Key="Base" TargetType="TextBlock">
        <Setter Property="FontFamily" Value="Sego Semibold"/>
        <Setter Property="FontSize" Value="15" />
    </Style>
    <Style x:Key="Body" TargetType="TextBlock">
        <Setter Property="FontFamily" Value="Sego Normal"/>
        <Setter Property="FontSize" Value="15" />
    </Style>
    <Style x:Key="Caption" TargetType="TextBlock">
        <Setter Property="FontFamily" Value="Sego Normal"/>
        <Setter Property="FontSize" Value="12" />
    </Style>   

</ResourceDictionary>

These styles are in my corporate style guide and I am re-sing them al over the place

now in my brand new application I can use the corporate style DLL from an internal NuGet package feed or I link it because It happens to be in my solution using the following resource dictionary

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    >
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/MyCorp.Wpf;component/Assets/TextStyles.xaml"/>
        <ResourceDictionary Source="/MyCorp.Wpf;component/Assets/Styles.xaml"/>
        <ResourceDictionary Source="/MyCorp.Wpf;component/Assets/Brushes.xaml"/>
        <ResourceDictionary Source="/MyCorp.Wpf;component/Assets/ColorStyles.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

I have no clue where the extra component come from, I just know I needed. then in my new application I just link it like so:

<Application x:Class="MyNew.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="ExternalResources.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            
            <BooleanToVisibilityConverter x:Key="VisibilityConverter"/>
        </ResourceDictionary>
    </Application.Resources>
</Application>

This way I have all external links in the ExternalResources.xaml where everyone understands where they came from and updating them is easy

I can then use the external resource definitions like any other in my windows, page and controls

<syncfusion:ChromelessWindow x:Class="IDPS.ChromelessWindow1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:IDPS"
        xmlns:r="clr-namespace:IDPS.Wpf.Properties;assembly=IDPS.Wpf"                     
        xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
        syncfusion:SfSkinManager.Theme="{syncfusion:SkinManagerExtension ThemeName=FluentDark}"
        mc:Ignorable="d"
       MinHeight="450" MinWidth="800">
    <Grid>
        <TextBlock Text="Hello world" Style="{StaticResource Title}"/>
    </Grid>
</syncfusion:ChromelessWindow>

My result

Related