2016年5月6日金曜日

Xamarin.Formsでカスタムコントロールを作るメモ

Xamarin.Formsでのカスタムコントロール構築

  • 共通プロジェクト側で、BoxViewを継承したクラスを作る
  • BoxViewを継承したクラスをメインのXamlページではっつける
  • プラットフォーム毎のプロジェクトでBoxViewの中を描画するためのRendererクラスを作る
// 例)
public class CustomControlClass : BoxView
{
}

RendererクラスのiOS/Android共通の要件は以下の通り。

  • assembly:ExportRenderer属性を設定する。
  • 例)[assembly:ExportRenderer(typeof(ShapeView), typeof(ShapeRenderer))]

RendererクラスのiOS固有の要件は以下の通り。

  • iOSの場合、VisualElementRenderer<>から継承する。 (Xamarin.Forms.Plarform.iOS名前空間で定義)
  • VisualElementRendererの型引数はターゲットとするViewBoxを継承したクラス。
  • Rendererクラスでは、Drawメソッド内にコントロール固有の描画コードを記述する。
//例)
[assembly:ExportRenderer(typeof(CustomControlClass), typeof(CustomControlRenderer))]
namespace Hoge.iOS
{
  public class CustomControlRenderer : VisualElementRenderer<CustomControlRenderer>
  {
    public override void Draw(System.Drawing.RectangleF rect)
    {
        // specify draw code here.
    }
  }
}

Android固有のRendererクラスの要件

  • Androidの場合、ViewRenderer<>から継承する。(Xamarin.Forms.Plarform.Android名前空間で定義)
  • ViewRenderer<>の型引数は2つで、一つ目は共通プロジェクトで定義したBoxViewを継承したクラス、2つ目は実際にコントロールの中身を描画するViewを継承したクラス(ここでは、CustomControlViewクラス)
// 例)

[assembly:ExportRenderer(typeof(CustomControlClass), typeof(CustomControlRenderer))]
namespace Hoge.Android
{
    public class CustomControlRenderer : ViewRenderer<CustomControlClass, CustomControlView>
    {
        protected override void OnElementChanged(ElementChangedEventArgs<CustomControlClass> e)
        {
            base.OnElementChanged(e);

            if(e.OldElement != null || this.Element == null)
            {
                return;
            }

            SetNativeControl(new Shape(Resources.DisplayMetrics.Density, Context)
            {
                ShapeView = Element
            });
        }

    }
}
  • Viewクラスの実装はOnDrawメソッド内でコントロール固有の描画コードを記述する。
// 例)
public class CustomControlView : Android.Views.View
{
    protected override void OnDraw(Canvas canvas)
    {
        // ここに固有の描画コードを記述する。
    }
}

カスタムコントロールの貼り付け方

共通クラスで書きます。
// 例) ここは前述の通り。

namespace Hoge
{
    public class CustomControlClass : BoxView
    {
    }
}
次に、これを使うxamlファイルは以下のように書きます。
<!--
    Hogeというアセンブリにカスタムコントロールが含まれている前提
-->
<ContentPage
    ....
    xmlns:ctrls="clr-namespace:Hoge;assembly=Hoge">

    <StackLayout>
        <ctrls:CustomControlClass />
    </StackLayout>
</ContentPage>

0 件のコメント: