testing
testing

Reputation: 20289

Can merged resource dictionaries access resources from App.xaml?

Can merged resource dictionaries access resources from App.xaml? The goal is to split the style to have it more readable.

This is what I'm looking for, but doesn't work in that way:

App.xaml in UWP project

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Styles\DefaultButtonStyle.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>

    <!-- other custom styles, definitions, ThemeDictionaries, ... -->
    <Color x:Key="Primary">#dfdfdf</Color>
</Application.Resources>

DefaultButtonStyle.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:AppName.UWP.Styles">

    <!-- some definitions -->
    <Style TargetType="Button" x:Key="DefaultButtonStyle">
        <!-- my styles -->
        <Setter Property="Background" Value="{StaticResource Primary}" />
    </Style>
</ResourceDictionary>

The app crashes with

Cannot find a Resource with the Name/Key Primary

I could put everything in one big style.xaml, or copy the needed values in each xaml file, but aren't there other options? Could a merged dictionary include another merged dictionary? Or something like that?

Upvotes: 2

Views: 1426

Answers (2)

Mark W
Mark W

Reputation: 1050

I have used separated dictionaries and have tried to keep them in order of usage. In my application I have:

  • ColorsAndBrushes.xaml
  • SizesAndLayout.xaml
  • DefaultStyles.xaml
  • NamedStyles.xaml

Where ColorsAndBrushes looks something like:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyApp.App.Styles">
    <!-- Colors -->
    <Color x:Key="Color_Banner">#FF333232</Color>
    <!--overridden from themeresource-->
    <Color x:Key="SystemChromeDisabledLowColor">#FFA8A49F</Color>
    <Color x:Key="SystemAccentColor">#FF2877CF</Color>
    <!-- /Colors -->

    <!-- Brushes -->
    <SolidColorBrush x:Key="Brush_Banner" Color="{StaticResource Color_Banner}" />
    <!-- /Brushes -->
</ResourceDictionary>

SizesAndLayout:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyApp.App.Styles">
    <!-- Padding -->
    <Thickness x:Key="Padding_Button">24,4</Thickness>
    <Thickness x:Key="Padding_Dialog">10</Thickness>
    <Thickness x:Key="Padding_Content">20</Thickness>
    <!-- /Padding -->

    <!-- Fonts -->
    <FontFamily x:Key="Font_DefaultFamily">Segoe UI</FontFamily>
    <FontWeight x:Key="Font_DefaultWeight">SemiLight</FontWeight>
    <FontWeight x:Key="Font_NormalWeight">Normal</FontWeight>
    <FontWeight x:Key="Font_BoldWeight">Semibold</FontWeight>
    <x:Double x:Key="ContentControlFontSizeSmall">11</x:Double>
    <x:Double x:Key="Font_NormalSize">20</x:Double>
    <x:Double x:Key="Font_H1Size">36</x:Double>
    <x:Double x:Key="Font_H2Size">28</x:Double>
    <!-- /Fonts -->
</ResourceDictionary>

DefaultStyles (apply to all of type - these use resources from other 2):

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyApp.App.Styles">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="ColorsAndBrushes.xaml" />
        <ResourceDictionary Source="SizesAndLayout.xaml" />
    </ResourceDictionary.MergedDictionaries>

    <Style TargetType="TextBlock">
        <Setter Property="FontFamily" Value="{StaticResource Font_DefaultFamily}" />
        <Setter Property="FontWeight" Value="{StaticResource Font_DefaultWeight}" />
        <Setter Property="FontSize" Value="{StaticResource Font_NormalSize}" />
        <Setter Property="TextWrapping" Value="WrapWholeWords" />
    </Style>
</ResourceDictionary>

and NamedStyles are overrides of the default:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyApp.App.Styles">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="ColorsAndBrushes.xaml" />
        <ResourceDictionary Source="SizesAndLayout.xaml" />
        <ResourceDictionary Source="DefaultStyles.xaml" />
    </ResourceDictionary.MergedDictionaries>
    <Style x:Key="FontStyle_H1" TargetType="TextBlock" BasedOn="{StaticResource FontStyle_Default}">
        <Setter Property="FontSize" Value="{StaticResource Font_H1Size}" />
        <Setter Property="Foreground" Value="{StaticResource Brush_DarkBlue}" />
        <Setter Property="Margin" Value="{StaticResource Margin_TitleFont}" />
    </Style>
</ResourceDictionary>

And finally, in the App.xaml:

<Application
    x:Class="MyApp.App.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyApp.App"
    RequestedTheme="Light">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Styles/ColorsAndBrushes.xaml" />
                <ResourceDictionary Source="Styles/SizesAndLayout.xaml" />
                <ResourceDictionary Source="Styles/DefaultStyles.xaml" />
                <ResourceDictionary Source="Styles/NamedStyles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

It works for me and keeps the XAML files smaller by using the smaller scoped files. However, I will say there are times that Visual Studio will give me a bunch of squigglies complaining that it can't figure out the namespace... but only when the file is open. I have also experienced that, while at runtime, the order of the declaration of static resources does not matter, at times, the designer within Visual Studio will not render the styles if they aren't in a top-down format.

Good luck!

Upvotes: 2

disklosr
disklosr

Reputation: 1626

Try this:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Styles\DefaultButtonStyle.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <!-- other custom styles, definitions, ThemeDictionaries, ... -->
        <Color x:Key="Primary">#dfdfdf</Color>
    </ResourceDictionary> 
</Application.Resources>

Upvotes: 0

Related Questions