Xamarin.Forms Visual Renderer を作成する

Xamarin.Forms Visual を使用すると、Xamarin.Forms ビューをサブクラス化することなく、レンダラーを作成して VisualElement オブジェクトに選択的に適用できます。 IVisual 型をその ExportRendererAttribute の一部として指定するレンダラーは、既定のレンダラーではなく、オプトイン ビューのレンダリングに使用されます。 レンダラーの選択時に、ビューの Visual プロパティが検査され、レンダラーの選択プロセスに含められます。

重要

現在、ビューのレンダリング後に Visual プロパティを変更することはできませんが、これは将来のリリースで変更される予定です。

Xamarin.Forms Visual レンダラーを作成して使用するプロセスは次のとおりです。

  1. 必要なビューのプラットフォーム レンダラーを作成します。 詳細については、レンダラーの作成に関するページを参照してください。
  2. IVisual から派生する型を作成します。 詳細については、「IVisual 型を作成する」を参照してください。
  3. レンダラーを修飾する ExportRendererAttribute の一部として IVisual 型を登録します。 詳細については、「IVisual 型を登録する」を参照してください。
  4. ビューの Visual プロパティを IVisual 名に設定して、Visual レンダラーを使用します。 詳細については、「Visual レンダラーを使用する」を参照してください。
  5. (省略可能) IVisual 型の名前を登録します。 詳細については、「IVisual 型の名前を登録する」を参照してください。

プラットフォームのレンダラーを作成する

レンダラー クラスの作成については、カスタム レンダラーに関するページを参照してください。 ただし、Xamarin.Forms Visual レンダラーは、ビューをサブクラス化しなくてもビューに適用されることに注意してください。

ここで説明するレンダラー クラスは、テキストを影付きで表示するカスタム Button を実装します。

iOS

次のコード例は、iOS 用のボタン レンダラーを示します。

public class CustomButtonRenderer : ButtonRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null)
        {
            // Cleanup
        }

        if (e.NewElement != null)
        {
            Control.TitleShadowOffset = new CoreGraphics.CGSize(1, 1);
            Control.SetTitleShadowColor(Color.Black.ToUIColor(), UIKit.UIControlState.Normal);
        }
    }
}

Android

次のコード例は、Android 用のボタン レンダラーを示します。

public class CustomButtonRenderer : Xamarin.Forms.Platform.Android.AppCompat.ButtonRenderer
{
    public CustomButtonRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null)
        {
            // Cleanup
        }

        if (e.NewElement != null)
        {
            Control.SetShadowLayer(5, 3, 3, Color.Black.ToAndroid());
        }
    }
}

IVisual 型を作成する

クロスプラットフォーム ライブラリで、IVisual から派生する型を作成します。

public class CustomVisual : IVisual
{
}

その後、レンダラー クラスに対して CustomVisual 型を登録し、Button オブジェクトがレンダラーの使用にオプトインできるようにします。

IVisual 型を登録する

プラットフォーム プロジェクトで、アセンブリ レベルで ExportRendererAttribute を追加します。

[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(CustomButtonRenderer), new[] { typeof(CustomVisual) })]
namespace VisualDemos.iOS
{
    public class CustomButtonRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            // ...
        }
    }
}

iOS プラットフォーム プロジェクトのこの例では、ExportRendererAttribute は、Button オブジェクト使用のレンダリングに CustomButtonRenderer クラスが使用されることを指定します。また、IVisual 型が 3 番目の引数として登録されています。 IVisual 型をその ExportRendererAttribute の一部として指定するレンダラーは、既定のレンダラーではなく、オプトイン ビューのレンダリングに使用されます。

Visual レンダラーを使用する

Button オブジェクトがレンダラー クラスの使用にオプトインできるようにするには、Visual プロパティを Custom に設定します。

<Button Visual="Custom"
        Text="CUSTOM BUTTON"
        BackgroundColor="{StaticResource PrimaryColor}"
        TextColor="{StaticResource SecondaryTextColor}"
        HorizontalOptions="FillAndExpand" />

Note

XAML では、型コンバーターを使用すると、Visual プロパティ値に "Visual" サフィックスを含める必要がなくなります。 ただし、完全な型名を指定することもできます。

同等の C# コードを次に示します。

Button button = new Button { Text = "CUSTOM BUTTON", ... };
button.Visual = new CustomVisual();

レンダラーの選択時に、ButtonVisual プロパティが検査され、レンダラーの選択プロセスに含められます。 レンダラーが見つからない場合は、既定の Xamarin.Forms レンダラーが使用されます。

次のスクリーンショットは、テキストが影付きで表示されている、レンダリングされた Button を示しています。

iOS および Android での、影のテキストを含むカスタム ボタンのスクリーンショット

IVisual 型の名前を登録する

VisualAttribute を使用すると、必要に応じて IVisual 型の別の名前を登録することができます。 この方法は、さまざまな Visual ライブラリ間の名前付けの競合を解決するとき、または単に型名とは異なる名前で Visual を参照したいときに使用できます。

VisualAttribute は、クロスプラットフォーム ライブラリまたはプラットフォーム プロジェクトのいずれかで、アセンブリ レベルで定義する必要があります。

[assembly: Visual("MyVisual", typeof(CustomVisual))]

その後、IVisual 型は、その登録名を使って使用することができます。

<Button Visual="MyVisual"
        ... />

Note

登録名で Visual を使用する場合は、"Visual" サフィックスを含める必要があります。