Xamarin Forms originally supported iOS, Android and Windows Phone Silverlight applications. The OnPlatform<T> class provides a mechanism for putting values directly into your XAML which are dependent on the host platform. This is often necessary to cope with different screen sizes and scaling behaviour across platforms. When Windows 8.1 and Windows Phone 8.1 were later added the OnPlatform class was not updated. This means that if you use OnPlatform it can’t provide a value for WinRT platforms. Without resorting to changing properties in the code-behind we wanted a way to set platform specific property values from XAML. Luckily the solution was quite simple – just 55 lines of code including doc comments and I’ve published the code here:-
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace InTheHand.Forms | |
{ | |
/// <summary> | |
/// Replacement for Xamarin.Forms.OnPlatform which supports the Windows (WinRT) platforms. | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
public sealed class OnPlatform2<T> | |
{ | |
public OnPlatform2() | |
{ | |
Android = default(T); | |
iOS = default(T); | |
WinPhone = default(T); | |
Windows = default(T); | |
Other = default(T); | |
} | |
public T Android{ get; set;} | |
public T iOS { get; set; } | |
public T WinPhone { get; set; } | |
/// <summary> | |
/// The value to use for WinRT (Windows Phone 8.1 and Windows 8.1). | |
/// </summary> | |
public T Windows { get; set; } | |
/// <summary> | |
/// Currently unused. | |
/// </summary> | |
public T Other { get; set; } | |
public static implicit operator T(InTheHand.Forms.OnPlatform2<T> onPlatform) | |
{ | |
switch(Xamarin.Forms.Device.OS) | |
{ | |
case Xamarin.Forms.TargetPlatform.Android: | |
return onPlatform.Android; | |
case Xamarin.Forms.TargetPlatform.iOS: | |
return onPlatform.iOS; | |
case Xamarin.Forms.TargetPlatform.WinPhone: | |
return onPlatform.WinPhone; | |
case Xamarin.Forms.TargetPlatform.Windows: | |
return onPlatform.Windows; | |
default: | |
return onPlatform.Other; | |
} | |
} | |
} | |
} |
To use in your XAML you just need to add an XML namespace declaration to your root node (e.g. ContentPage)
xmlns:forms="clr-namespace:InTheHand.Forms;assembly=YOURASSEMBLY"
Then use the class from your XAML. It works with any type which can be represented as a string in XAML. e.g.
<Grid.Padding>
<forms:OnPlatform2 x:TypeArguments="Thickness" iOS="5" Android="5" Windows="0,10,0,5"/>
</Grid.Padding>