Xamarin逆引きTips
Xamarin.Formsでビヘイビアーを使用するには?
サブクラス化することなく、UIコントロールに機能を追加できる「ビヘイビアー」の基本的な使い方を説明する。
Xamarin.Formsのバージョン1.3以降で追加された新機能の一つにビヘイビアーがある。ビヘイビアーを使用すると、サブクラス化することなく、UIコントロールに機能を追加できる。
今回は、このビヘイビアーの利用方法について解説する。
- *1 なお本Tipsは、Windows上でVisual Studio 2013を使用してXamarin.Forms開発をすることを前提としている(※編集部注: Mac上のXamarin Studioでも同様の手順で、本稿の内容が実現できることは確認している)。使用しているXamarin.Formsのバージョンは、プロジェクト作成時に利用されている「1.3.1.6296」である。
1. シナリオ
最初に、電子メールアドレスの入力と[送信]ボタンというような簡単なUI画面を題材として、入力内容が適正かどうかをテキスト色の変化で視覚的にユーザーに伝えるようにする。
続いて、入力の内容が適正なときだけ、[送信]ボタンが押せるように拡張する。
2. Xamarin.Formsプロジェクトを作成する
メニューバーの[ファイル]-[新規作成]-[プロジェクト]から表示したダイアログで、[テンプレート]-[Visual C#]-[Mobile Apps]-[Blank App (Xamarin.Forms Portable)]を選択し、名前を「BehaviorSample」として[OK]ボタンを押す。
3.テキスト入力とボタン
最初に、ビヘイビアーを適用するための簡単な入力画面を作成する。
テキスト入力とボタンを配置した画面を表示するには、App.csファイルを以下のように修正する。
using Xamarin.Forms;
namespace BehaviorSample {
public class App : Application {
public App() {
MainPage = new MyPage();
}
……省略……
}
class MyPage : ContentPage {
public MyPage() {
var button = new Button { // <-1
Text = "Send",
HorizontalOptions = LayoutOptions.Center,
};
var entry = new Entry { // <-2
WidthRequest = 200,
Placeholder = "user@example.com",
HorizontalOptions = LayoutOptions.Center,
};
Content = new StackLayout { // <-3
Padding = new Thickness(0,Device.OnPlatform(40,20,20),0,0),
Children = { entry, button }
};
}
}
}
|
最初に、Button
コントロール(1)と、Entry
コントロール(2)を生成している。
Button
コントロールには、「送信」を意味するようにSendと表示し、Entry
コントロールには、プレースホルダーとしてuser@example.comを表示して電子メールアドレスの入力を促すようにする。また、どちらも画面の中央に配置されるようにHorizontalOptions
プロパティは、LayoutOptions.Centerとしている。
生成した2つのコントロールは、StackLayout
で上下になるように配置している(3)。
このコードを実行すると次のような画面になる。
4. 拡張ビヘイビアークラス
ビヘイビアーを実装するには、Behavior
クラス(Xamarin.Forms
名前空間)を継承した拡張ビヘイビアークラスを定義する必要がある。
拡張ビヘイビアークラスを追加したApp.csファイルは、次のようになる。
using System.Text.RegularExpressions;
……省略……
namespace BehaviorSample {
class MyPage : ContentPage {
public MyPage() {
……省略……
var entry = new Entry {
WidthRequest = 200,
Placeholder = "user@example.com",
HorizontalOptions = LayoutOptions.Center,
Behaviors = { new EmailBehavior() } // <-1
};
……省略……
}
}
public class EmailBehavior : Behavior<Entry> { // <-2
private readonly Regex _regex = new Regex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"); // <-3
protected override void OnAttachedTo(Entry bindable) { // <-4
bindable.TextChanged += CheckEmail;
}
protected override void OnDetachingFrom(Entry bindable) { // <-5
bindable.TextChanged -= CheckEmail;
}
private void CheckEmail(object sender, TextChangedEventArgs e) { // <-6
//文字列がEmailとして正しいかどうかのチェック
var m = _regex.Match(e.NewTextValue);
//正かどうかによってテキストの色を変化させる
((Entry) sender).TextColor = m.Success ? Color.Default : Color.Red;
}
}
}
|
2では、Behavior
クラスを継承した拡張ビヘイビアークラス(ここでは、クラス名をEmailBehavior
とした)を作成している。このとき、このビヘイビアーを適用するコントロール(ここでは、Entry
コントロール)の型を指定する必要がある。
Behavior
クラスを継承すると、OnAttachedTo
メソッド(4)および、OnDetachingFrom
メソッド(5)のオーバーライドが可能になる。これらのメソッドは、それぞれ、対象コントロール(=Entry
コントロール)に、このビヘイビアーが適用された時および、削除された時に呼び出される。このため、ビヘイビアーで使用するオブジェクトの生成および、破棄などの処理が必要なときは、ここに記述することになる。サンプルコードでは、イベントへのハンドラー(CheckEmail
メソッド)の追加と削除を行っている。
イベントハンドラーとして用意したCheckEmail
メソッドは、文字列が電子メールアドレスとして適切であるか否かを判断してEntry
コントロールのテキスト色を変化させるものである(6)。なお、適正かどうかの判断は、正規表現クラスを使用した(3)。
最後に、定義したビヘイビアーの適用であるが、これは、対象コントロールのBehaviors
プロパティに追加することで行う(1)。
このコードを実行すると次のような画面になる。
5. 別コントロールとの連携
ビヘイビアーの基本的な役割は、既存のコントロールを拡張することであるが、応用として、この拡張ビヘイビアークラスに状態を表すプロパティなどを実装して、他のコントロールと連携することも可能である。
状態を表すプロパティを実装した拡張ビヘイビアークラスは次のようになる。
……省略……
namespace BehaviorSample {
……省略……
public class EmailBehavior : Behavior<Entry> {
public bool IsValid { get; private set; } // <-1
……省略……
private void CheckEmail(object sender, TextChangedEventArgs e) {
var m = _regex.Match(e.NewTextValue);
((Entry) sender).TextColor = m.Success ? Color.Default : Color.Red;
IsValid = m.Success; // <-2
}
}
}
|
1では、電子メールアドレスとして有効かどうかの状態を表すプロパティ(IsValid
)を追加した。
そして、判定した結果を、このプロパティに設定している(2)。
このプロパティ値を使用して、ボタンの有効/無効を変化させるには、App.csファイルを以下のように修正する。
……省略……
namespace BehaviorSample {
……省略……
class MyPage : ContentPage {
public MyPage() {
var emailBehavior = new EmailBehavior(); // <-1
var button = new Button {
Text = "Send",
HorizontalOptions = LayoutOptions.Center,
IsEnabled = emailBehavior.IsValid // <-2
};
var entry = new Entry {
WidthRequest = 200,
Placeholder = "user@example.com",
HorizontalOptions = LayoutOptions.Center,
Behaviors = { emailBehavior }
};
entry.TextChanged += (sender, args) =>{
button.IsEnabled = emailBehavior.IsValid; // <-3
};
Content = new StackLayout {
Padding = new Thickness(0, Device.OnPlatform(40, 20, 20), 0, 0),
Children = {entry, button}
};
}
}
……省略……
}
|
拡張ビヘイビアークラスは、変数として生成する(1)。
そして、Button
オブジェクトの有効/無効は、この変数のプロパティ値で初期化した(2)。
また、Entry
コントロールのテキスト変化時も、Button
オブジェクトの有効/無効が変化するようにした(3)。
このコードを実行すると次のような画面になる。
電子メールアドレスとして不完全な場合(左)は、無効、完全となった時点(右)で有効になる。
【コラム】進化するXamarin.Forms
Xamarin.Formsは、昨年5月、Xamarin 3と共に新たに登場したフレームワークであり、まだ、誕生して1年にも満たない。しかし、誕生後すごい勢いで進化を遂げており、今回紹介したビヘイビアーも、昨年末に追加された機能の1つである。
つい先日、アナウンスされたXamarin.Forms.Windows(2015年3月24日現在はアルファ版)では、新たに、Windows Phone RT(※「RT」とはSilverlightアプリではない「WinRTアプリ」のこと)やストアアプリも同時に開発できるようになった。
6. まとめ
今回は、既存のコントロールをサブクラス化することなく、機能拡張できるビヘイビアーについて解説した。また、応用として、状態を表すプロパティなどによる、他のコントロールと連携する方法についても併せて紹介した。
ビヘイビアーによって、よりユーザーに優しい、また、フールプルーフなUI構築が可能になる。
※以下では、本稿の前後を合わせて5回分(第40回~第44回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
40. Xamarin.Formsで地図の現在位置やピンの表示、縮尺や地図タイプの変更を行うには?(Xamarin.Forms.Maps使用)
Xamarin.Forms.Mapsコントロールで利用可能な機能として、「現在位置」や「衛星写真」「ピン立て」「スライダーコントロールによる地図の拡大・縮小」などを解説する。
43. MvvmCrossでコマンドバインディングをするには?
MvvmCrossでは、画面でのイベント発生をViewModelに通知するためにコマンドバインディングを使用する。iOS/Androidにおける、その基本的な実装方法を説明する。
44. Xamarin.FormsでListViewのコンテキストアクションを使用するには?
リストの1つをスライド(iOS)もしくは長押し(Android)されたらメニューを表示する「コンテキストアクション」の基本的な使い方を説明する。