xamarinxamarin.formsresourcedictionarymergeddictionaries

Avoid to refer styles in all pages - Xamarin.Forms


I'm working on a Xamarin Forms app for mobile cross platform. I found how to apply styles to my pages and controls in this way:

Styles/HeaderStyle.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="App.HeaderStyle">
    <Style x:Key="Header" TargetType="StackLayout">
        <Setter Property="Orientation" Value="Horizontal"/>
        <Setter Property="Padding" Value="5"/>
        <Setter Property="BackgroundColor" Value="Green"/>
    </Style>
</ResourceDictionary>

Views/Page.xaml

<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="App.HomePage"
    xmlns:local="clr-namespace:App;"
    NavigationPage.HasNavigationBar="false">
    <ContentPage.Resources>
        <ResourceDictionary MergedWith="local:HeaderStyle">
        </ResourceDictionary>
    </ContentPage.Resources>
    <!-- Some other page content -->
</ContentPage>

I have some doubt about this implementation: - I can't figure out how to add multiple style files - I've to add the style file references to all the pages

I've tried to add the reference in App.xaml in some way like this

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="theme:Resources1"/>
    <ResourceDictionary Source="theme:Resources2"/>
</ResourceDictionary.MergedDictionaries>

But without success.


Solution

  • If you have styles that you use everywhere, you can put them in a global style.

    In your App.xaml you can define a ResourceDictionary just like you have now. For example:

    <Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Styles.App">
        <Application.Resources>
            <ResourceDictionary>
                <Style x:Key="buttonStyle" TargetType="Button">
                    <Setter Property="HorizontalOptions" Value="Center" />
                    <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                    <Setter Property="BorderColor" Value="Lime" />
                    <Setter Property="BorderRadius" Value="5" />
                    <Setter Property="BorderWidth" Value="5" />
                    <Setter Property="WidthRequest" Value="200" />
                    <Setter Property="TextColor" Value="Teal" />
                </Style>
            </ResourceDictionary>
        </Application.Resources>
    </Application>
    

    Then in your page you should be able to refer to them without having to declare the merging of the dictionary, like so:

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Styles.ApplicationStylesPage" Title="Application" Icon="xaml.png">
        <ContentPage.Content>
            <StackLayout Padding="0,20,0,0">
                <Button Text="These buttons" Style="{StaticResource buttonStyle}" />
                <Button Text="are demonstrating" Style="{StaticResource buttonStyle}" />
                <Button Text="application style overrides" Style="{StaticResource buttonStyle}" />
            </StackLayout>
        </ContentPage.Content>
    </ContentPage>
    

    If you were to override the style, you could do so by declaring a style in that page, styles lower in the hierarchy take precendence over the styles higher up. You could also choose not to add the x:Key attribute on a style to make it implicit. That way you do not have to declare the Style property on a control.