Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
Xamarin逆引きTips

Xamarin逆引きTips

Xamarin.Formsでビヘイビアーを使用するには?

2015年3月26日

サブクラス化することなく、UIコントロールに機能を追加できる「ビヘイビアー」の基本的な使い方を説明する。

古谷 誠進(@furuya02
  • このエントリーをはてなブックマークに追加

 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]ボタンを押す。

図1 「Blank App (Xamarin.Forms Portable)」の新規作成

3.テキスト入力とボタン

 最初に、ビヘイビアーを適用するための簡単な入力画面を作成する。

 テキスト入力とボタンを配置した画面を表示するには、App.csファイルを以下のように修正する。

C#
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 }
      };
    }
  }
}
テキスト入力とボタンを配置したコード(App.cs)

 最初に、Buttonコントロール(1)と、Entryコントロール(2)を生成している。

 Buttonコントロールには、「送信」を意味するようにSendと表示し、Entryコントロールには、プレースホルダーとしてuser@example.comを表示して電子メールアドレスの入力を促すようにする。また、どちらも画面の中央に配置されるようにHorizontalOptionsプロパティは、LayoutOptions.Centerとしている。

 生成した2つのコントロールは、StackLayoutで上下になるように配置している(3)。

 このコードを実行すると次のような画面になる。

図2 テキスト入力とボタンを配置した画面(Android/iOS)

4. 拡張ビヘイビアークラス

 ビヘイビアーを実装するには、Behaviorクラス(Xamarin.Forms名前空間)を継承した拡張ビヘイビアークラスを定義する必要がある。

 拡張ビヘイビアークラスを追加したApp.csファイルは、次のようになる。

C#
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;

    }
  }

}
ビヘイビアーを実装したコード(App.cs)

 2では、Behaviorクラスを継承した拡張ビヘイビアークラス(ここでは、クラス名をEmailBehaviorとした)を作成している。このとき、このビヘイビアーを適用するコントロール(ここでは、Entryコントロール)の型を指定する必要がある。

 Behaviorクラスを継承すると、OnAttachedToメソッド(4)および、OnDetachingFromメソッド(5)のオーバーライドが可能になる。これらのメソッドは、それぞれ、対象コントロール(=Entryコントロール)に、このビヘイビアーが適用された時および、削除された時に呼び出される。このため、ビヘイビアーで使用するオブジェクトの生成および、破棄などの処理が必要なときは、ここに記述することになる。サンプルコードでは、イベントへのハンドラー(CheckEmailメソッド)の追加と削除を行っている。

 イベントハンドラーとして用意したCheckEmailメソッドは、文字列が電子メールアドレスとして適切であるか否かを判断してEntryコントロールのテキスト色を変化させるものである(6)。なお、適正かどうかの判断は、正規表現クラスを使用した(3)。

 最後に、定義したビヘイビアーの適用であるが、これは、対象コントロールのBehaviorsプロパティに追加することで行う(1)。

 このコードを実行すると次のような画面になる。

図3 ビヘイビアーを適用したEntryコントロール(Android/iOS)

電子メールアドレスとして不完全な場合(左)は、テキストが赤色となり、完全となった時点(右)で黒色になる。

5. 別コントロールとの連携

 ビヘイビアーの基本的な役割は、既存のコントロールを拡張することであるが、応用として、この拡張ビヘイビアークラスに状態を表すプロパティなどを実装して、他のコントロールと連携することも可能である。

 状態を表すプロパティを実装した拡張ビヘイビアークラスは次のようになる。

C#
……省略……

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
    }
  }
}
状態を表すプロパティを追加したコード(App.cs)

 1では、電子メールアドレスとして有効かどうかの状態を表すプロパティ(IsValid)を追加した。

 そして、判定した結果を、このプロパティに設定している(2)。

 このプロパティ値を使用して、ボタンの有効/無効を変化させるには、App.csファイルを以下のように修正する。

C#
……省略……

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}
      };
    }
  }

  ……省略……
}
Entryコントロールの状態でボタンの有効無効を変化させるコード(App.cs)

 拡張ビヘイビアークラスは、変数として生成する(1)。

 そして、Buttonオブジェクトの有効/無効は、この変数のプロパティ値で初期化した(2)。

 また、Entryコントロールのテキスト変化時も、Buttonオブジェクトの有効/無効が変化するようにした(3)。

 このコードを実行すると次のような画面になる。

図4 Entryコントロールの拡張ビヘイビアークラスでButtonコントロールを制御(Android/iOS)

電子メールアドレスとして不完全な場合(左)は、無効、完全となった時点(右)で有効になる。

【コラム】進化するXamarin.Forms

 Xamarin.Formsは、昨年5月、Xamarin 3と共に新たに登場したフレームワークであり、まだ、誕生して1年にも満たない。しかし、誕生後すごい勢いで進化を遂げており、今回紹介したビヘイビアーも、昨年末に追加された機能の1つである。

 つい先日、アナウンスされたXamarin.Forms.Windows(2015年3月24日現在はアルファ版)では、新たに、Windows Phone RT(「RT」とはSilverlightアプリではない「WinRTアプリ」のこと)やストアアプリも同時に開発できるようになった。

図5 筆者が最近作成中のTwitterクライアントをストアアプリに対応させてみたもの
図6 NuGetパッケージとして公開されているXamarin.Forms.Windows

6. まとめ

 今回は、既存のコントロールをサブクラス化することなく、機能拡張できるビヘイビアーについて解説した。また、応用として、状態を表すプロパティなどによる、他のコントロールと連携する方法についても併せて紹介した。

 ビヘイビアーによって、よりユーザーに優しい、また、フールプルーフなUI構築が可能になる。

※以下では、本稿の前後を合わせて5回分(第40回~第44回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

Xamarin逆引きTips
40. Xamarin.Formsで地図の現在位置やピンの表示、縮尺や地図タイプの変更を行うには?(Xamarin.Forms.Maps使用)

Xamarin.Forms.Mapsコントロールで利用可能な機能として、「現在位置」や「衛星写真」「ピン立て」「スライダーコントロールによる地図の拡大・縮小」などを解説する。

Xamarin逆引きTips
41. MvvmCrossでプロパティバインディングをするには?

MvvmCrossでの画面表示に必要なプロパティバインディングについて、iOS/Androidの基本的な実装を説明する。

Xamarin逆引きTips
42. 【現在、表示中】≫ Xamarin.Formsでビヘイビアーを使用するには?

サブクラス化することなく、UIコントロールに機能を追加できる「ビヘイビアー」の基本的な使い方を説明する。

Xamarin逆引きTips
43. MvvmCrossでコマンドバインディングをするには?

MvvmCrossでは、画面でのイベント発生をViewModelに通知するためにコマンドバインディングを使用する。iOS/Androidにおける、その基本的な実装方法を説明する。

Xamarin逆引きTips
44. Xamarin.FormsでListViewのコンテキストアクションを使用するには?

リストの1つをスライド(iOS)もしくは長押し(Android)されたらメニューを表示する「コンテキストアクション」の基本的な使い方を説明する。

サイトからのお知らせ

Twitterでつぶやこう!