平台專用
平臺特定專案可讓您取用只能在特定平臺上使用的功能,而不需要實作自定義轉譯器或效果。
透過 XAML 或 Fluent 程式代碼 API 取用平臺專屬的程式如下:
xmlns
為命名空間新增宣告或using
指示詞Xamarin.Forms.PlatformConfiguration
。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 上,這是
- 使用 Fluent API 從 XAML 或從程式碼套用
On<T>
平臺特定的 。 的值T
可以是命名空間中的iOS
Xamarin.Forms.PlatformConfiguration
、Android
或Windows
型別。
注意
請注意,嘗試在無法使用平臺的平臺上取用平臺特定,將不會產生錯誤。 相反地,程式代碼會在不套用平臺特定的情況下執行。
透過 Fluent 程式代碼 API 傳回IPlatformElementConfiguration
物件取用On<T>
的平臺特定專案。 這可讓多個平臺特定專案在具有方法串聯的相同物件上叫用。
如需 所提供Xamarin.Forms平臺特定項目的詳細資訊,請參閱 iOS 平臺特定、Android 平臺特定和 Windows 平臺特定。
建立平臺特定專案
廠商可以使用 Effects 建立自己的平臺特定專案。 效果會提供特定功能,然後透過平臺特定公開。 結果是一種效果,可透過 XAML 和 Fluent 程式代碼 API 更輕鬆地取用。
建立平台專屬的程式如下:
- 實作特定功能做為效果。 如需詳細資訊,請參閱 建立效果。
- 建立將公開 Effect 的平臺特定類別。 如需詳細資訊,請參閱 建立平臺特定類別。
- 在平臺特定類別中,實作附加屬性,以允許透過 XAML 取用平臺特定的屬性。 如需詳細資訊,請參閱 新增附加屬性。
- 在平臺特定類別中,實作擴充方法,以允許透過 Fluent 程式代碼 API 取用平台專屬。 如需詳細資訊,請參閱 新增擴充方法。
- 修改 Effect 實作,只有在與 Effect 相同的平臺上叫用平臺特定時,才會套用 Effect。 如需詳細資訊,請參閱 建立效果。
將 Effect 公開為平臺特有的結果,就是效果可以透過 XAML 和 Fluent 程式代碼 API 更輕鬆地取用。
注意
其設想廠商會使用這項技術來建立自己的平臺特定專案,以方便用戶取用。 雖然使用者可以選擇建立自己的平臺特定專案,但應該注意,它需要比建立和使用效果更多的程序代碼。
範例應用程式示範平臺 Shadow
特定,可將陰影新增至控件所 Label
顯示的文字:
範例應用程式會在每個平臺上實作 Shadow
平台專屬,以方便瞭解。 不過,除了每個平臺特定的 Effect 實作之外,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
附加屬性是用來將 Effect 新增MyCompany.LabelShadowEffect
至 ,並將它從 附加類別的控件Shadow
中移除。 此附加屬性會註冊 OnIsShadowedPropertyChanged
方法;當屬性的值變更時,就會執行此方法。 接著,這個方法會呼叫 AttachEffect
或 DetachEffect
方法,根據附加屬性的值 IsShadowed
來新增或移除效果。 修改控件的 Effects
集合,即會將 Effect 新增至控件或從控件中移除。
注意
請注意,效果的解析方式是指定解析組名串連的值,以及效果實作上指定的唯一標識符。 如需詳細資訊,請參閱 建立效果。
如需附加屬性的詳細資訊,請參閱附加屬性。
新增擴充方法
擴充方法必須新增至 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
已在實作 Effect 的相同平臺上叫用平臺特定。 這個檢查是使用 OnThisPlatform
方法執行的。
Shadow.IsShadowed
如果附加的屬性值在運行時間變更,效果需要藉由移除陰影來回應。 因此,覆寫的 OnElementPropertyChanged
方法版本是用來藉由呼叫 UpdateShadow
方法來響應可繫結的屬性變更。
如需建立效果的詳細資訊,請參閱 建立效果 和 傳遞效果參數做為附加屬性。
取用平臺特定
平台 Shadow
專用是藉由將 Shadow.IsShadowed
附加屬性設定為 boolean
值,以在 XAML 中取用:
<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);