How to combine imported and local resources in WPF user control

WpfXamlResources

Wpf Problem Overview


I'm writing several WPF user controls that need both shared and individual resources.

I have figured out the syntax for loading resources from a separate resource file:

<UserControl.Resources>
    <ResourceDictionary Source="ViewResources.xaml" />
</UserControl.Resources>

However, when I do this, I cannot also add resources locally, like:

<UserControl.Resources>
    <ResourceDictionary Source="ViewResources.xaml" />
    <!-- Doesn't work: -->
    <ControlTemplate x:Key="validationTemplate">
        ...
    </ControlTemplate>
    <style x:key="textBoxWithError" TargetType="{x:Type TextBox}">
        ...
    </style>
    ...
</UserControl.Resources>

I've had a look at ResourceDictionary.MergedDictionaries, but that only lets me merge more than one external dictionary, not define further resources locally.

I must be missing something trivial?

It should be mentioned: I'm hosting my user controls in a WinForms project, so putting shared resources in App.xaml is not really an option.

Wpf Solutions


Solution 1 - Wpf

I figured it out. The solution involves MergedDictionaries, but the specifics must be just right, like this:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ViewResources.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <!-- This works: -->
        <ControlTemplate x:Key="validationTemplate">
            ...
        </ControlTemplate>
        <style x:key="textBoxWithError" TargetType="{x:Type TextBox}">
            ...
        </style>
        ...
    </ResourceDictionary>
</UserControl.Resources>

That is, the local resources must be nested within the ResourceDictionary tag. So the example here is incorrect.

Solution 2 - Wpf

You can define local resources inside MergedDictionaries section:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!-- import resources from external files -->
            <ResourceDictionary Source="ViewResources.xaml" />
            
            <ResourceDictionary>
                <!-- put local resources here -->
                <Style x:key="textBoxWithError" TargetType="{x:Type TextBox}">
                    ...
                </Style>
                ...
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

Solution 3 - Wpf

Use MergedDictionaries.

I got the following example from here.

File1

<ResourceDictionary 
  xmlns=" http://schemas.microsoft.com/winfx/2006/xaml/presentation "
  xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml " > 
  <Style TargetType="{x:Type TextBlock}" x:Key="TextStyle">
    <Setter Property="FontFamily" Value="Lucida Sans" />
    <Setter Property="FontSize" Value="22" />
    <Setter Property="Foreground" Value="#58290A" />
  </Style>
</ResourceDictionary>

File 2

   <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
          <ResourceDictionary Source="TextStyle.xaml" />
        </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary> 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTor HaugenView Question on Stackoverflow
Solution 1 - WpfTor HaugenView Answer on Stackoverflow
Solution 2 - WpfLu55View Answer on Stackoverflow
Solution 3 - WpfPreet SanghaView Answer on Stackoverflow