P3PPP
P3PPP

Reputation: 153

Xamarin.Forms: How can I load ResourceDictionary from another file?

I wrote following code, but XamlParseException has bean thrown. ("StaticResource not found for key CustomColor")

MyPage.xaml

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XFApp11.MyPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="CustomResource.xaml" />
            </ResourceDictionary.MergedDictionaries> 
        </ResourceDictionary>
    </ContentPage.Resources>

    <ContentPage.Content>
        <BoxView Color="{StaticResource CustomColor}" />
    </ContentPage.Content>
</ContentPage>

CustomResource.xaml (build action = EmbeddedResource)

<?xml version="1.0" encoding="UTF-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <Color x:Key="CustomColor">#004B86</Color>
</ResourceDictionary>

Upvotes: 14

Views: 14933

Answers (5)

Kornelis
Kornelis

Reputation: 163

After also struggleing with this Topic I came to a solution using the MergedDiciontaries

<Application ... xmlns:resources="clr-namespace:AppName.Resources;assembly=AppName" xmlns:theme="clr-namespace:Company.Design;assembly=Company.Design">
    <Application.Resources>
        <ResourceDictionary >
            <ResourceDictionary.MergedDictionaries>
                <theme:Theme/> <!--ResourceDictionary from another assembly -->
                <resources:StylesAndTemplates/> <!--ResourceDictionary from the same assembly also StylesAndTemplates which uses colors / style from "Theme" ResourceDictionary -->
            </ResourceDictionary.MergedDictionaries>
        ...
        </ResourceDictionary>
        ...
    </Application.Resources>
    ...
</Application>

Upvotes: 1

A few notes after hours fighting with this:

  • MergedWith is deprecated. Use Source instead.
  • Despite what the official tutorial says, it doesn't seem to be possible to load a resource dictionary defined within a separate ContentPage. The resource dictionary needs to be its own .xaml file.
  • Despite what another answer says, the value of Source is just the name of the .xaml file, not the path to it.
  • From this comment, the .xaml file containing your shared resources MUST:
    • ..have a root-element of type ResourceDictionary
    • ..have a .xaml.cs backing file (deleting it causes it to silently fail)
    • ..inherit from ResourceDictionary in the backing file
    • ..be in the same assembly as the .xaml using it (it's apparently possible to share styles across assemblies using MergedDictionaries, but I wasn't able to get this to work)

Upvotes: 1

fmaccaroni
fmaccaroni

Reputation: 3916

From Xamarin.Forms 3.0 MergedWith has been deprecated and should not be used.

Now you can use either Source or MergeDictionaries.

MyResource.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="UI.MyResource">
    <Style TargetType="Label">
        <Setter Property="TextColor" Value="Blue" />
    </Style>
</ResourceDictionary>

So, if MyResource.xaml is in the same assembly you can use directly:

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="UI.AnotherResource"
    Source="MyResource.xaml">
</ResourceDictionary>

Otherwise (MyResource.xaml is on another assembly):

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:otherresources="clr-namespace:OtherAssembly.UI.Resources"
    x:Class="UI.AnotherResource">
    <ResourceDictionary.MergedDictionaries>
        <otherresources:MyResource />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

Some things to take into consideration:

  • Source: It can only be used in XAML, and the value is the path to the xaml file (always in same assembly)
  • MergeDictionaries: It can be used regardless of the assembly where the resource reside

More info in Xamarin Forms Resource Dictionaries

Upvotes: 4

Adam
Adam

Reputation: 16199

Merged Dictionaries aren't supported in Xamarin Forms XAML below 2.1.0

The only way you can do it, is to put it in another page and then load it up in code behind and reference it via DynamicResource instead of StaticResource.

I explain this more here: http://www.xamarinhelp.com/styling-uiux-day-11/

However as of 2.1.0-pre1 (released this week), you can now do templating, which is another way to do this. Jason Smith has blogged about it: http://xfcomplete.net/general/2016/01/20/control-templates/

Update: As of 2.3.0 you can do a Merged Dictionary with an attribute called MergedWith.

Create a new XAML File

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="UIDemo.Style.NewStyle">
    <Style TargetType="Label">
        <Setter Property="TextColor" Value="Blue" />
    </Style>
</ResourceDictionary>

Now in your ContentPage use the MergedWith attribute on your ResourceDictionary.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:theme="clr-namespace:UIDemo.Style"
             x:Class="UIDemo.MainPage">
    <ContentPage.Resources>
        <ResourceDictionary MergedWith="theme:NewStyle" />
    </ContentPage.Resources>
    <Grid>
        <Label Text="Hello" />
    </Grid>
</ContentPage>

Upvotes: 9

Ahmed Alejo
Ahmed Alejo

Reputation: 2431

As of 2.3.0 can officially merge Resource dictionaries in xaml observe the following example

BlueTheme.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="UI.Themes.BlueTheme">
    <Style TargetType="Label">
        <Setter Property="TextColor" Value="Blue" />
    </Style>
</ResourceDictionary>

App.xaml

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:theme="clr-namespace:UI.Themes"
             x:Class="UI.App">
    <Application.Resources>
        <ResourceDictionary MergedWith="themes:BlueTheme" />
    </Application.Resources>
    <Label Text="Hello" />
</Application>

Upvotes: 15

Related Questions