Creating a Reusable Styles Assembly for Xamarin.Forms

0 Comments

Xamarin.Forms 2.3.1 introduced the MergedWith feature for ResourceDictionary and lets you combine (merge) resource dictionaries. I'll show how you can use this to create a separate assembly that contains styles and other items you might want to reuse across multiple app projects. Head over to the merged dictionary documentation to brush up on the syntax or to review the basics of ResourceDictionary.

You'll need to use Xamarin.Forms version 2.3.4.184-pre1 or newer for this to work. There is another issue reported on Bugzilla that is fixed in pre2.

Create a PCL project

You probably want to reuse some styles across multiple apps so it makes sense to put these in a PCL project. It's quick and simple to get the project ready for containing our shared styles.

  • Create a PCL project
  • Add the Xamarin.Forms NuGet package
  • Remove the auto-generated class file
  • Add a new Cross-Platform -> Xamarin.Forms XAML Page to the project
  • Change the <ContentPage> to <ResourceDictionary>.
  • Change the *.xaml.csfile to inherit fromResourceDictionary` as well.
  • Remove any existing controls that were inserted into the xaml page, usually a <Label>.

Now you are ready to drop in some styles. Add a <Style> to your new XAML ResourceDictionary.

<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="SharedStylesLib.Theme">
  <Style TargetType="Label">
    <Setter Property="TextColor" Value="Blue" />
  </Style>
</ResourceDictionary>

Ready for Reuse

Now that you have your theme library, add a reference to it in your app project's PCL project. Now you can take advantage of the MergeWith feature in your App.xaml file.

<Application xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:theme="clr-namespace:SharedStylesLib;assembly=SharedStylesLib"
            x:Class="SharedStylesTest.App">
  <Application.Resources>
    <ResourceDictionary MergedWith="theme:Theme"/>      
  </Application.Resources>  
</Application>

I've added a new namespace declaration for the theme library, xmlns:theme="clr-namespace:SharedStylesLib;assembly=SharedStylesLib" and created a new ResourceDictionary that merges the one from our theme assembley, MergedWith="theme:Theme". I defined an implicit style, so all my Label controls will have a text color of blue.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"      
             x:Class="SharedStylesTest.Page1">
  <Label Text="The text will be blue!" VerticalOptions="Center" HorizontalOptions="Center"/>
</ContentPage>

What about other things?

This can be useful for other reusable components too, like converters. Just add it to your theme library.

<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:SharedStylesLib;assembly=SharedStylesLib"
             x:Class="SharedStylesLib.Theme">
  ...
  <local:MyConverter x:Key="MyConverter"/>
</ResourceDictionary>

And now it's ready to use in your app project.

<Label Text="{Binding MyText, Converter={StaticResource MyConverter}}" />

You can find the full source to this sample on my GitHub page. Let me know if you find some other useful things to include. Have fun!

Comments