Xamarin.Forms
カスタムコントロールの作成
サーチ…
前書き
すべてのXamarin.Forms
ビューには、ネイティブコントロールのインスタンスを作成する各プラットフォーム用のレンダラーが付属しています。ビューが特定のプラットフォームでレンダリングされると、 ViewRenderer
クラスがインスタンス化されます。
これを行うプロセスは次のとおりです。
Xamarin.Formsカスタムコントロールを作成します。
Xamarin.Formsからカスタムコントロールを使用します。
各プラットフォームのコントロールのカスタムレンダラーを作成します。
CheckBoxコントロールの実装
この例では、AndroidとiOS用のカスタムチェックボックスを実装します。
カスタムコントロールの作成
namespace CheckBoxCustomRendererExample
{
public class Checkbox : View
{
public static readonly BindableProperty IsCheckedProperty = BindableProperty.Create<Checkbox, bool>(p => p.IsChecked, true, propertyChanged: (s, o, n) => { (s as Checkbox).OnChecked(new EventArgs()); });
public static readonly BindableProperty ColorProperty = BindableProperty.Create<Checkbox, Color>(p => p.Color, Color.Default);
public bool IsChecked
{
get
{
return (bool)GetValue(IsCheckedProperty);
}
set
{
SetValue(IsCheckedProperty, value);
}
}
public Color Color
{
get
{
return (Color)GetValue(ColorProperty);
}
set
{
SetValue(ColorProperty, value);
}
}
public event EventHandler Checked;
protected virtual void OnChecked(EventArgs e)
{
if (Checked != null)
Checked(this, e);
}
}
}
まず、Androidのカスタムレンダラーから、このソリューションのAndroid
部分に新しいクラス( CheckboxCustomRenderer
)を作成します。
注意すべきいくつかの重要な詳細:
- レンダラーが
Xamarin.Forms
登録されるように、クラスの先頭にExportRenderer属性を設定する必要があります。このようにして、Xamarin.Forms
はAndroid
上でCheckbox
オブジェクトを作成しようとするときに、このレンダラーを使用します。 -
OnElementChanged
メソッドでは、ほとんどの作業を行います。ここでは、ネイティブコントロールをインスタンス化して設定します。
カスタムコントロールを消費する
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:CheckBoxCustomRendererExample" x:Class="CheckBoxCustomRendererExample.CheckBoxCustomRendererExamplePage">
<StackLayout Padding="20">
<local:Checkbox Color="Aqua" />
</StackLayout>
</ContentPage>
各プラットフォームでのカスタムレンダラーの作成
カスタムレンダラークラスを作成するプロセスは次のとおりです。
- カスタムコントロールをレンダリングする
ViewRenderer<T1,T2>
クラスのサブクラスを作成します。最初の型の引数はレンダラーのためのカスタムコントロール、この場合はCheckBox
なければなりません。 2番目の引数は、カスタムコントロールを実装するネイティブコントロールです。 - カスタムコントロールを描画する
OnElementChanged
メソッドをオーバーライドし、カスタムコントロールをカスタマイズするロジックを記述します。このメソッドは、対応するXamarin.Forms
コントロールが作成されたときに呼び出されます。 - カスタムレンダラークラスに
ExportRenderer
属性を追加して、Xamarin.Forms
カスタムコントロールのレンダリングに使用することを指定します。この属性は、Xamarin.Forms
カスタムレンダラーを登録するために使用されます。
Android用カスタムレンダラーの作成
[assembly: ExportRenderer(typeof(Checkbox), typeof(CheckBoxRenderer))]
namespace CheckBoxCustomRendererExample.Droid
{
public class CheckBoxRenderer : ViewRenderer<Checkbox, CheckBox>
{
private CheckBox checkBox;
protected override void OnElementChanged(ElementChangedEventArgs<Checkbox> e)
{
base.OnElementChanged(e);
var model = e.NewElement;
checkBox = new CheckBox(Context);
checkBox.Tag = this;
CheckboxPropertyChanged(model, null);
checkBox.SetOnClickListener(new ClickListener(model));
SetNativeControl(checkBox);
}
private void CheckboxPropertyChanged(Checkbox model, String propertyName)
{
if (propertyName == null || Checkbox.IsCheckedProperty.PropertyName == propertyName)
{
checkBox.Checked = model.IsChecked;
}
if (propertyName == null || Checkbox.ColorProperty.PropertyName == propertyName)
{
int[][] states = {
new int[] { Android.Resource.Attribute.StateEnabled}, // enabled
new int[] {Android.Resource.Attribute.StateEnabled}, // disabled
new int[] {Android.Resource.Attribute.StateChecked}, // unchecked
new int[] { Android.Resource.Attribute.StatePressed} // pressed
};
var checkBoxColor = (int)model.Color.ToAndroid();
int[] colors = {
checkBoxColor,
checkBoxColor,
checkBoxColor,
checkBoxColor
};
var myList = new Android.Content.Res.ColorStateList(states, colors);
checkBox.ButtonTintList = myList;
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (checkBox != null)
{
base.OnElementPropertyChanged(sender, e);
CheckboxPropertyChanged((Checkbox)sender, e.PropertyName);
}
}
public class ClickListener : Java.Lang.Object, IOnClickListener
{
private Checkbox _myCheckbox;
public ClickListener(Checkbox myCheckbox)
{
this._myCheckbox = myCheckbox;
}
public void OnClick(global::Android.Views.View v)
{
_myCheckbox.IsChecked = !_myCheckbox.IsChecked;
}
}
}
}
iOS向けカスタムレンダラーの作成
iOSではチェックボックスに組み込まれていないので、最初にCheckBoxView
を作成し、次にXamarin.Formsチェックボックスのレンダラーを作成します。
CheckBoxView
はchecked_checkbox.pngとunchecked_checkbox.pngという2つの画像に基づいているため、 Color
プロパティは無視されます。
CheckBoxビュー:
namespace CheckBoxCustomRendererExample.iOS
{
[Register("CheckBoxView")]
public class CheckBoxView : UIButton
{
public CheckBoxView()
{
Initialize();
}
public CheckBoxView(CGRect bounds)
: base(bounds)
{
Initialize();
}
public string CheckedTitle
{
set
{
SetTitle(value, UIControlState.Selected);
}
}
public string UncheckedTitle
{
set
{
SetTitle(value, UIControlState.Normal);
}
}
public bool Checked
{
set { Selected = value; }
get { return Selected; }
}
void Initialize()
{
ApplyStyle();
TouchUpInside += (sender, args) => Selected = !Selected;
// set default color, because type is not UIButtonType.System
SetTitleColor(UIColor.DarkTextColor, UIControlState.Normal);
SetTitleColor(UIColor.DarkTextColor, UIControlState.Selected);
}
void ApplyStyle()
{
SetImage(UIImage.FromBundle("Images/checked_checkbox.png"), UIControlState.Selected);
SetImage(UIImage.FromBundle("Images/unchecked_checkbox.png"), UIControlState.Normal);
}
}
}
CheckBoxカスタムレンダラー:
[assembly: ExportRenderer(typeof(Checkbox), typeof(CheckBoxRenderer))]
namespace CheckBoxCustomRendererExample.iOS
{
public class CheckBoxRenderer : ViewRenderer<Checkbox, CheckBoxView>
{
/// <summary>
/// Handles the Element Changed event
/// </summary>
/// <param name="e">The e.</param>
protected override void OnElementChanged(ElementChangedEventArgs<Checkbox> e)
{
base.OnElementChanged(e);
if (Element == null)
return;
BackgroundColor = Element.BackgroundColor.ToUIColor();
if (e.NewElement != null)
{
if (Control == null)
{
var checkBox = new CheckBoxView(Bounds);
checkBox.TouchUpInside += (s, args) => Element.IsChecked = Control.Checked;
SetNativeControl(checkBox);
}
Control.Checked = e.NewElement.IsChecked;
}
Control.Frame = Frame;
Control.Bounds = Bounds;
}
/// <summary>
/// Handles the <see cref="E:ElementPropertyChanged" /> event.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName.Equals("Checked"))
{
Control.Checked = Element.IsChecked;
}
}
}
}
結果:
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow