Wesley Vrancken
Wesley Vrancken

Reputation: 474

Nesting ResourceDictionaries with MergedDictionaries in UWP

I'm trying to split up a ResourceDictionary containing styles for multiple controls in our current UWP application. The file has grown to about 3000 lines and has become a living hell to manage, so I decided to split it up into smaller, more specific ResourceDictionaries and include them using MergedDictionaries.

App.xaml

<common:BootStrapper x:Class="Asteria.Ion.App"
                     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                     xmlns:common="using:Template10.Common"
                     xmlns:styles="using:Asteria.Ion.Styles"
                     RequestedTheme="Dark">

    <common:BootStrapper.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Styles\Custom.xaml" />
                <ResourceDictionary Source="Styles\CustomControls.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </common:BootStrapper.Resources>
</common:BootStrapper>

CustomControls.xaml contains references to other ResourceDictionaries.

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="using:Template10.Controls"
    xmlns:behaviors="using:Template10.Behaviors"
    xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:local="using:Asteria.Ion.Styles">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Shared.xaml" />
        <ResourceDictionary Source="Templates.xaml" />
        <ResourceDictionary Source="ComponentBlock.xaml" />
        <ResourceDictionary Source="FlowAgent.xaml" />
        <ResourceDictionary Source="Planning.xaml" />
        <ResourceDictionary Source="ProjectDialog.xaml" />
        <ResourceDictionary Source="Inspector.xaml" /-->
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

This will always produce the following exception: Failed to assign to property 'Windows.UI.Xaml.ResourceDictionary.Source' because the type 'Windows.Foundation.String' cannot be assigned to the type 'Windows.Foundation.Uri'. [Line: 12 Position: 37]

I've tried changing the source URI numerous times, but it keeps giving this error. Only commenting out all the ResourceDictionary elements in CustomControls.xaml helps. But then I get exceptions concerning missing styles of course.

Some URI formats I've tried:

None of them work.

Any advice would be appreciated.

Upvotes: 3

Views: 1318

Answers (2)

Wesley Vrancken
Wesley Vrancken

Reputation: 474

In the end it had nothing to do with the URI structure, but with a combination of ThemeDictionaries and MergedDictionaries.

What was working before:

In App.Resources:

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="Styles/Themes.xaml" />
    <ResourceDictionary Source="Styles/CustomControls.xaml" />
</ResourceDictionary.MergedDictionaries>

Where Themes.xaml contained ThemeDictionaries and CustomControls.xaml contained <Styles> ( a lot of them ).

After splitting CustomControls.xaml, it no longer contained any styles, but only MergedDictionaries. Looking something like this:

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="ControlStyles/ProjectDialog.xaml" />
    <ResourceDictionary Source="ControlStyles/Inspector.xaml" />
</ResourceDictionary.MergedDictionaries>

Inspector.xaml contained a Style using {ThemeResource} and it appears that's where it went wrong. The solution/work-around in the end was to include a MergedDictionaries with a references to Themes.xaml in Inspector.xaml.

Now if anyone can explain the exact reasoning behind this solution, I'd be much obliged.

Upvotes: 4

Elvis Xia - MSFT
Elvis Xia - MSFT

Reputation: 10841

From the error message,XAML Compiler failed to translate the Source Property of nested ResourceDictionaries. The easiest and fastest workaround is to add the nested ResourceDictionaries in App.Xaml.cs:

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
   ...
    var applicationMergedDics = Application.Current.Resources.MergedDictionaries;
    applicationMergedDics[0].MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("ms-appx:///Styles/Shared.xaml") });
    applicationMergedDics[0].MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("ms-appx:///Styles/Templates.xaml") });
    ...
    rootFrame.Navigate(typeof(MainPage), e.Arguments);
}

Notes: Don't forget to remove the MergedDictionaries in CustomControls.xaml. And the error will be gone.

Upvotes: 2

Related Questions