XF Platform Specific Styling

Introduction

Sometimes you need to specify XAML that is specific to the platform. Xamarin Forms already has a special class to help with this called OnPlatform. But I find that it isn’t always granular enough to handle the different instances of Windows: Windows, Windows Phone, Windows Tablet and Xbox. We can define our own custom handler to help us with this.

It looks like the following in XAML.

<!--
here is the declaration in the content page attributes:
xmlns:h="clr-namespace:AppName.Helpers"
-->
<Label Text="Display Custom Platform Styling">
    <Label.Margin>
        <h:OnCustomPlatform
            x:TypeArguments="Thickness"
            Android="5,40"
            iOS="10,20"
            Windows="20"
            WinPhone="4,8,4,8"
            WinTablet="12,8,12,8"
            Xbox="40" />
    </Label.Margin>
</Label>

A couple of things about the above code: the h: refers to the namespace that contains our OnCustomPlatform class. The other thing to note is that I don’t know if the Device and TargetIdiom objects in Xamarin Forms work with the Xbox, so use with caution if you are going to try this with an Xbox app.

How the Class Works

using Xamarin.Forms;

public sealed class OnCustomPlatform<T>
{
    public T Android { get; set; } = default(T);
    public T iOS { get; set; } = default(T);
    public T WinPhone { get; set; } = default(T);
    public T Windows { get; set; } = default(T);
    public T WinTablet { get; set; } = default(T);
    public T Xbox { get; set; } = default(T);
    public T Other { get; set; } = default(T);

    public static implicit operator T(OnCustomPlatform<T> p)
    {
        switch (Device.RuntimePlatform)
        {
            case Device.Android:
                return p.Android;
            case Device.iOS:
                return p.iOS;
            case Device.Windows:
                if (Device.Idiom == TargetIdiom.Desktop)
                    return p.Windows;
                else if (Device.Idiom == TargetIdiom.Phone)
                    return p.WinPhone;
                else if (Device.Idiom == TargetIdiom.Tablet)
                    return p.WinTablet;
                else if (Device.Idiom == TargetIdiom.TV)
                    return p.Xbox;
                else
                    return default(T);
            default:
                return p.Other;
        }
    }
}

And that is all there is. It is actually surprisingly simple to do though I admit, after a while it gets pretty verbose the more complex you get with your page.