我已经看到了几种似乎可行的选项,可以用于编写特定于平台的XAML:
内联
<OnPlatform x:Key="MyKey"
x:TypeArguments="x:Single"
Android="30"
iOS="20">
</OnPlatform>
嵌套值
<OnPlatform x:TypeArguments="Thickness">
<On Platform="Android" Value="0, 0, 0, 0"/>
<On Platform="iOS" Value="0, 20, 0, 0"/>
</OnPlatform>
例如here。
嵌套为内容
<OnPlatform x:Key="MyOtherKey" x:TypeArguments="x:Double">
<On Platform="Android">40</On>
<On Platform="iOS">40</On>
</OnPlatform>
has been valid, but is now obsolete之类的东西,根据this blog post,似乎与我在本文中称为“内联”的版本相对应。
这三个选项之间的(技术)区别是什么?
我提出这个问题的动机:
当我将“嵌套为内容”用作静态资源时,它对我有用,但是当它传递给我的IValueConverter
时,所有特定于平台的值都设置为0。当我使用“嵌套”时,也会发生同样的情况。具有“价值”版本。但是过时的“内联”版本可以按预期工作。因此,这些选项在后台的工作方式似乎有所不同。
我刚刚找到了source,似乎新版本的相关附加功能是此代码段:
#pragma warning disable RECS0108 // Warns about static fields in generic types
static readonly IValueConverterProvider s_valueConverter = DependencyService.Get<IValueConverterProvider>();
#pragma warning restore RECS0108 // Warns about static fields in generic types
public static implicit operator T(OnPlatform<T> onPlatform)
{
foreach (var onPlat in onPlatform.Platforms) {
if (onPlat.Platform == null)
continue;
if (!onPlat.Platform.Contains(Device.RuntimePlatform))
continue;
if (s_valueConverter == null)
continue;
return (T)s_valueConverter.Convert(onPlat.Value, typeof(T), null, null);
}
if (!onPlatform.useLegacyFallback)
return onPlatform.hasDefault ? onPlatform.@default : default(T);
//legacy fallback
#pragma warning disable 0618, 0612
return Device.OnPlatform(iOS: onPlatform.iOS, Android: onPlatform.Android, WinPhone: onPlatform.WinPhone);
#pragma warning restore 0618, 0612
}
根据使用的版本,有时似乎返回OnPlatform
,有时甚至返回默认值。 (我仍然希望能得到一个可以更彻底地解释其含义的答案,以及使用过时版本的反对之处)