平台特定的功能让你可以使用仅在特定平台上提供的功能,而无需实现自定义呈现器或效果。
通过 XAML 或 Fluent 代码 API 使用特定于平台的过程如下所示:
- 为
Xamarin.Forms.PlatformConfiguration命名空间添加xmlns声明或using指令。 - 为包含特定于平台的功能的命名空间添加
xmlns声明或using指令:- 在 iOS 上,这是
Xamarin.Forms.PlatformConfiguration.iOSSpecific命名空间。 - 在 Android 上,这是
Xamarin.Forms.PlatformConfiguration.AndroidSpecific命名空间。 对于 Android AppCompat,这是Xamarin.Forms.PlatformConfiguration.AndroidSpecific.AppCompat命名空间。 - 在通用 Windows 平台上,这是
Xamarin.Forms.PlatformConfiguration.WindowsSpecific命名空间。
- 在 iOS 上,这是
- 使用
On<T>Fluent API 通过 XAML 或代码应用特定于平台的内容。T的值可以是Xamarin.Forms.PlatformConfiguration命名空间中的iOS、Android或Windows类型。
注意
请注意,尝试在特定于平台的内容不可用的平台上使用它将不会造成错误。 相反,代码将执行,而不会应用特定于平台的内容。
通过 On<T> Fluent 代码 API 使用的特定于平台的内容会返回 IPlatformElementConfiguration 对象。 这样,就可以使用方法级联在同一对象上调用多个特定于平台的内容。
有关 Xamarin.Forms 提供的特定于平台的内容的详细信息,请参阅 iOS 平台特定、Android 平台特定和 Windows 平台特定。
创建平台特定内容
供应商可以使用效果创建自己的平台特定内容。 效果可提供特定功能,功能通过特定于平台的内容公开。 结果是一种效果,可通过 XAML 和 Fluent 代码 API 更轻松地使用。
创建特定于平台的内容的过程如下所示:
- 将特定功能实现为效果。 有关详细信息,请参阅创建效果。
- 创建一个平台特定的类,该类将公开效果。 有关详细信息,请参阅创建特定于平台的类。
- 在特定于平台的类中,实现附加属性,以允许通过 XAML 使用特定于平台的内容。 有关详细信息,请参阅添加附加属性。
- 在特定于平台的类中,实现扩展方法,以允许通过 Fluent 代码 API 使用特定于平台的内容。 有关详细信息,请参阅添加扩展方法。
- 修改效果实现,以便仅在与效果相同的平台上调用特定于平台的内容时应用效果。 有关详细信息,请参阅创建效果。
将效果公开为特定于平台的内容的结果是,可以通过 XAML 和 Fluent 代码 API 更轻松地使用效果。
注意
预计供应商将使用此技术创建自己的平台特定内容,以便用户轻松使用它们。 虽然用户可以选择创建自己的平台特定内容,但应指出,它需要比创建和使用效果更多的代码。
示例应用程序展示了特定于平台的 Shadow,它将向 Label 控件显示的文本添加阴影:

示例应用程序将在每个平台上实现特定于平台的 Shadow,以便于读者理解。 但是,除了每个特定于平台的效果实现之外,阴影类的实现对于每个平台来说基本上都是相同的。 因此,本指南重点介绍阴影类的实现以及单个平台上的关联效果。
有关效果的详细信息,请参阅使用效果自定义控件。
创建特定于平台的类
特定于平台的类创建为 public static 类:
namespace MyCompany.Forms.PlatformConfiguration.iOS
{
public static Shadow
{
...
}
}
以下部分讨论 Shadow 平台特定内容和关联的效果的实现。
添加附加属性
必须将附加属性添加到 Shadow 平台特定内容,以允许通过 XAML 使用:
namespace MyCompany.Forms.PlatformConfiguration.iOS
{
using System.Linq;
using Xamarin.Forms;
using Xamarin.Forms.PlatformConfiguration;
using FormsElement = Xamarin.Forms.Label;
public static class Shadow
{
const string EffectName = "MyCompany.LabelShadowEffect";
public static readonly BindableProperty IsShadowedProperty =
BindableProperty.CreateAttached("IsShadowed",
typeof(bool),
typeof(Shadow),
false,
propertyChanged: OnIsShadowedPropertyChanged);
public static bool GetIsShadowed(BindableObject element)
{
return (bool)element.GetValue(IsShadowedProperty);
}
public static void SetIsShadowed(BindableObject element, bool value)
{
element.SetValue(IsShadowedProperty, value);
}
...
static void OnIsShadowedPropertyChanged(BindableObject element, object oldValue, object newValue)
{
if ((bool)newValue)
{
AttachEffect(element as FormsElement);
}
else
{
DetachEffect(element as FormsElement);
}
}
static void AttachEffect(FormsElement element)
{
IElementController controller = element;
if (controller == null || controller.EffectIsAttached(EffectName))
{
return;
}
element.Effects.Add(Effect.Resolve(EffectName));
}
static void DetachEffect(FormsElement element)
{
IElementController controller = element;
if (controller == null || !controller.EffectIsAttached(EffectName))
{
return;
}
var toRemove = element.Effects.FirstOrDefault(e => e.ResolveId == Effect.Resolve(EffectName).ResolveId);
if (toRemove != null)
{
element.Effects.Remove(toRemove);
}
}
}
}
IsShadowed 附加属性用于向 Shadow 类附加到的控件添加 MyCompany.LabelShadowEffect 效果以及从其移除该效果。 该附加属性注册属性值更改时执行的 OnIsShadowedPropertyChanged 方法。 反过来,此方法会调用 AttachEffect 或 DetachEffect 方法,以基于 IsShadowed 附加属性的值添加或移除效果。 通过修改控件的 Effects 集合,在控件中添加或移除效果。
注意
请注意,效果是通过指定一个值来解析的,该值是在效果实现上指定的解析组名称和唯一标识符的串联。 有关详细信息,请参阅创建效果。
有关附加属性的详细信息,请参阅附加属性。
添加扩展方法
必须将扩展方法添加到 Shadow 平台特定内容,以允许通过 Fluent 代码 API 使用:
namespace MyCompany.Forms.PlatformConfiguration.iOS
{
using System.Linq;
using Xamarin.Forms;
using Xamarin.Forms.PlatformConfiguration;
using FormsElement = Xamarin.Forms.Label;
public static class Shadow
{
...
public static bool IsShadowed(this IPlatformElementConfiguration<iOS, FormsElement> config)
{
return GetIsShadowed(config.Element);
}
public static IPlatformElementConfiguration<iOS, FormsElement> SetIsShadowed(this IPlatformElementConfiguration<iOS, FormsElement> config, bool value)
{
SetIsShadowed(config.Element, value);
return config;
}
...
}
}
IsShadowed 和 SetIsShadowed 扩展方法会分别调用 IsShadowed 附加属性的 get 和 set 访问器。 每个扩展方法都对 IPlatformElementConfiguration<iOS, FormsElement> 类型进行操作,该类型会指定可以在 iOS 中的 Label 实例上调用的特定于平台的内容。
创建效果
Shadow 平台特定内容会将 MyCompany.LabelShadowEffect 添加到 Label,以及将其移除。 以下代码示例展示了 iOS 项目的 LabelShadowEffect 实现:
[assembly: ResolutionGroupName("MyCompany")]
[assembly: ExportEffect(typeof(LabelShadowEffect), "LabelShadowEffect")]
namespace ShadowPlatformSpecific.iOS
{
public class LabelShadowEffect : PlatformEffect
{
protected override void OnAttached()
{
UpdateShadow();
}
protected override void OnDetached()
{
}
protected override void OnElementPropertyChanged(PropertyChangedEventArgs args)
{
base.OnElementPropertyChanged(args);
if (args.PropertyName == Shadow.IsShadowedProperty.PropertyName)
{
UpdateShadow();
}
}
void UpdateShadow()
{
try
{
if (((Label)Element).OnThisPlatform().IsShadowed())
{
Control.Layer.CornerRadius = 5;
Control.Layer.ShadowColor = UIColor.Black.CGColor;
Control.Layer.ShadowOffset = new CGSize(5, 5);
Control.Layer.ShadowOpacity = 1.0f;
}
else if (!((Label)Element).OnThisPlatform().IsShadowed())
{
Control.Layer.ShadowOpacity = 0;
}
}
catch (Exception ex)
{
Console.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
}
}
UpdateShadow 方法会设置 Control.Layer 属性以创建阴影,前提是 IsShadowed 附加属性设置为 true,且已在实现效果的同一平台上调用了 Shadow 特定于平台的内容。 此检查通过 OnThisPlatform 方法执行。
如果 Shadow.IsShadowed 附加属性值在运行时发生更改,则效果需要通过移除阴影来响应。 因此,OnElementPropertyChanged 方法的替代版本用于通过调用 UpdateShadow 方法来响应可绑定属性更改。
有关创建效果的详细信息,请参阅创建效果以及传递效果参数作为附加属性。
使用特定于平台的内容
通过将 Shadow.IsShadowed 附加属性设置为 boolean 值,在 XAML 中使用 Shadow 特定于平台的内容:
<ContentPage xmlns:ios="clr-namespace:MyCompany.Forms.PlatformConfiguration.iOS" ...>
...
<Label Text="Label Shadow Effect" ios:Shadow.IsShadowed="true" ... />
...
</ContentPage>
或者,可以使用 Fluent API 从 C# 使用它:
using Xamarin.Forms.PlatformConfiguration;
using MyCompany.Forms.PlatformConfiguration.iOS;
...
shadowLabel.On<iOS>().SetIsShadowed(true);