プラットフォーム固有設定
プラットフォーム固有設定により、カスタムのレンダラーやエフェクトを実装しなくても、特定のプラットフォームのみで利用できる機能を使用できます。
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 では、これは
- XAML から、または
On<T>
fluent API を使用したコードからプラットフォーム固有設定を適用します。T
の値には、Xamarin.Forms.PlatformConfiguration
名前空間のiOS
、Android
、Windows
型のいずれかを指定できます。
Note
プラットフォーム固有設定を、それが利用できないプラットフォーム上で使用しようとしても、エラーは発生しないことに注意してください。 代わりに、コードはプラットフォーム固有設定が適用されない状態で実行されます。
On<T>
fluent コード API を通して使用されるプラットフォーム固有設定は IPlatformElementConfiguration
オブジェクトを返します。 これにより、メソッド カスケードを使用して同じオブジェクト上で複数のプラットフォーム固有設定を呼び出すことができます。
Xamarin.Forms によって提供されるプラットフォーム固有設定の詳細については、「iOS プラットフォーム固有設定」、「Android プラットフォーム固有設定」、および「Windows プラットフォーム固有設定」を参照してください。
プラットフォーム固有設定の作成
ベンダーは、独自のプラットフォーム固有設定をエフェクトと共に作成できます。 エフェクトは特定の機能を提供するもので、プラットフォーム固有設定を通して公開されます。 その結果、エフェクトは XAML と fluent コード API を通してより簡単に使用できます。
プラットフォーム固有設定の作成プロセスは以下のとおりです。
- 特定の機能をエフェクトとして実装します。 詳細については、「エフェクトの作成」を参照してください。
- エフェクトを公開するプラットフォーム固有クラスを作成します。 詳細については、「プラットフォーム固有クラスの作成」を参照してください。
- プラットフォーム固有クラスで、添付プロパティを実装して、XAML を通してプラットフォーム固有設定を使用できるようにします。 詳細については、「添付プロパティの追加」を参照してください。
- プラットフォーム固有クラスで、拡張メソッドを実装して、fluent コード API を通してプラットフォーム固有設定を使用できるようにします。 詳細については、「拡張メソッドの追加」を参照してください。
- エフェクトの実装を変更して、エフェクトが適用されるのは、プラットフォーム固有設定がエフェクトと同じプラットフォームで呼び出された場合だけになるようにします。 詳細については、「エフェクトの作成」を参照してください。
プラットフォーム固有設定としてエフェクトを公開する結果、XAML と fluent コード API を通してエフェクトをより簡単に使用できるようになります。
Note
ユーザーによる使用が簡単になるように、ベンダーはこの手法を使用して独自のプラットフォーム固有設定を作成することが想定されています。 ユーザーは独自のプラットフォーム固有設定を作成することもできますが、エフェクトを作成して使用するよりも多くのコードが必要になることに注意する必要があります。
このサンプル アプリケーションでは、Label
コントロールによって表示されるテキストにシャドウを追加する Shadow
プラットフォーム固有設定を見ていただきます。
理解しやすいように、このサンプル アプリケーションでは、Shadow
プラットフォーム固有設定がプラットフォームごとに実装されています。 ただし、各プラットフォーム固有のエフェクトの実装を別にすると、Shadow クラスの実装は各プラットフォームで大部分は同じです。 したがって、このガイドでは 1 つのプラットフォームでの Shadow クラスの実装および関連するエフェクトに焦点を当てます。
エフェクトの詳細については、「エフェクトを使用したコントロールのカスタマイズ」を参照してください。
プラットフォーム固有クラスの作成
プラットフォーム固有設定は以下のように public static
クラスとして作成されます。
namespace MyCompany.Forms.PlatformConfiguration.iOS
{
public static Shadow
{
...
}
}
以降のセクションでは、Shadow
プラットフォーム固有設定および関連するエフェクトの実装について説明します。
添付プロパティの追加
XAML を通した使用を可能にするためには、以下のように添付プロパティを Shadow
プラットフォーム固有設定に追加する必要があります。
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
コレクションを変更することによって、コントロールに追加またはコントロールから削除されます。
Note
エフェクトは、エフェクトの実装で指定された解決グループ名と一意識別子を連結した値を指定することで解決されることに注意してください。 詳細については、「エフェクトの作成」を参照してください。
添付プロパティについて詳しくは、「添付プロパティ」をご覧ください。
拡張メソッドの追加
fluent コード API を通した使用を可能にするには、以下のように拡張メソッドを Shadow
プラットフォーム固有設定に追加する必要があります。
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);
}
}
}
}
IsShadowed
添付プロパティが true
に設定されている場合、かつ Shadow
プラットフォーム固有設定がこのエフェクトの実装対象と同じプラットフォームで呼び出された場合に、UpdateShadow
メソッドは Control.Layer
プロパティを設定して影を作成します。 このチェックは 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);