Xamarin逆引きTips

Xamarin逆引きTips

Xamarin.Formsでトリガーを使用するには?

2015年4月8日

イベントやプロパティの変化に応じたコントロールの外観の変更をXAMLだけで実装できるトリガーの基本的な使用方法を解説する。

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

 Xamarin.Formsのバージョン1.3以降で追加された機能の1つにトリガーがある。トリガーを使用すると、イベントやプロパティの変化に応じたコントロールの外観の変更をXAMLだけで実装できる。

 今回は、このトリガーの利用方法について解説する。

  • *1 なお本Tipsは、Windows上でVisual Studio 2013を使用してXamarin.Forms開発をすることを前提としている(編集部注: Mac上のXamarin Studioでも同様の手順で、本稿の内容が実現できることは確認している)。使用しているXamarin.Formsのバージョンは、プロジェクト作成時に利用されている「1.3.1.6296」である。

1. トリガーの種類

 トリガーは、変化を検出する対象に応じて、次の4種類がある。

  • プロパティトリガー(Property Trigger): プロパティ値の変化
  • データトリガー(Data Trigger): 別コントロールのプロパティ値の変化
  • イベントトリガー(Event Trigger): イベント
  • マルチトリガー(Multi Trigger): 複数トリガーの複合状態

 また、トリガーは、個々のコントロールに直接指定して定義するだけでなく、ページ単位などで複数のコントロールに一気に指定することもできる。

 以下、それぞれのトリガーの利用方法について解説する。

2. Xamarin.Formsプロジェクトの作成と、XAMLによるトップページ

 メニューバーの[ファイル]-[新規作成]-[プロジェクト]から表示したダイアログで、[テンプレート]-[Visual C#]-[Mobile Apps]-[Blank App (Xamarin.Forms Portable)]を選択し、名前を「TriggerSample」として[OK]ボタンを押す(図1)。

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

 続いて、ソリューションエクスプローラーのPCL(共通プロジェクト)で右クリックして表示されるメニューから[追加]-[新しい項目]を選択し、表示されたダイアログで[インストール済み]-[Visual C#]-[Forms Xaml Page]を選択し、名前を「MainPage.cs」として[OK]ボタンを押す(図2)。

図2 「Forms Xaml Page」の新規作成

 作成したXAMLページ(MainPage)をアプリの最初のページにするためには、App.csファイルを以下のように修正する。

C#
using Xamarin.Forms;

namespace TriggerSample {
  public class App : Application {
    public App(){
      MainPage = new MainPage();
    }

    ……省略……
  }
}
XAMLページをメインページとするコード(App.cs)

3. プロパティトリガー

 プロパティトリガーを使用するには、MainPage.xamlファイルを以下のように修正する。

XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       x:Class="TriggerSample.MainPage">
  <StackLayout Padding="20">
  <Entry Placeholder="Enter First Name"> <!-- 1 -->
    <Entry.Triggers> <!-- 2 -->
      <Trigger TargetType="Entry" Property="IsFocused" Value="True"> <!-- 3 -->
      <Setter Property="BackgroundColor" Value="Aqua" /> <!-- 4 -->
      </Trigger>
    </Entry.Triggers>
  </Entry>
  </StackLayout>
</ContentPage>
プロパティトリガーを実装したXAMLコード(MainPage.xaml)

 StackLayoutの中に、Entryコントロールを1つ配置し(1)、Triggersプロパティを指定した(2)。

 トリガーは、IsFocusedプロパティがTrueとなったときに(3)、BackgroundColorプロパティが水色(Aqua)になるように指定している(4)。

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

図3 プロパティトリガーの実行画面(Android/iOS)

Entryコントロールにフォーカスがあるときだけ、背景色が水色に変わる。

4. ページ全体のトリガー

 トリガーは、個々のコントロールに指定するだけでなく、ページのリソースに定義して、ページ全体に影響させることもできる。ページ全体のトリガーを指定するには、MainPage.xamlファイルを以下のように修正する。

XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="TriggerSample.MainPage">

  <ContentPage.Resources> <!-- 1 -->
    <ResourceDictionary>
      <Style TargetType="Entry"> <!-- 2 -->
        <Style.Triggers>
          <Trigger  TargetType="Entry" Property="IsFocused" Value="True"> <!-- 3 -->
            <Setter Property="BackgroundColor" Value="Yellow" /> <!-- 4 -->
          </Trigger>
        </Style.Triggers>
      </Style>
    </ResourceDictionary>
  </ContentPage.Resources>
  
  <StackLayout Padding="20">
    <Entry Placeholder="Enter First Name" /> <!-- 5 -->
    <Entry Placeholder="Enter Last Name" /> <!-- 6 -->
  </StackLayout>
</ContentPage>
ページ全体のトリガーを実装したXAMLコード(MainPage.xaml)

 ページのリソースとして(1)、Entryコントロールに適用されるスタイルを定義する(2)。

 トリガーは、先ほどと同じで、IsFocusedプロパティがTrueとなったときに(3)、BackgroundColorプロパティが、今度は黄色(Yellow)になるように指定した(4)。

 ここまでの定義が終わると、このページ内で使用する全てのEntryコントロールに、このトリガーが適用されることになる(56)。

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

図4 ページ全体のトリガーの実行画面(Android/iOS)

2つのEntryコントロールに、同じトリガーが適用されている

5. データトリガー

 データトリガーを使用するには、MainPage.xamlファイルを以下のように修正する。

XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="TriggerSample.MainPage">

  <StackLayout Padding="20">
    <Entry x:Name="entry" Placeholder="required field" Text=""/> <!-- 1 -->
      <Button Text="OK"> <!-- 2 -->
        <Button.Triggers>
          <DataTrigger TargetType="Button" Binding="{Binding Source={x:Reference entry},Path=Text.Length}" Value="0"> <!-- 3 -->
            <Setter Property="IsEnabled" Value="False" /> <!-- 4 -->
          </DataTrigger>
      </Button.Triggers>
    </Button>
  </StackLayout>

</ContentPage>
データトリガーを実装したXAML(MainPage.xaml)

 StackLayoutの中に、Entryコントロールと(1)、Buttonコントロールを配置した(2)。

 ButtonコントロールのTriggersプロパティには、データトリガーが指定されており、EntryコントロールのTextプロパティのサイズが0のとき(3)、自身のIsEnabledプロパティがFalseとなるようになっている(4)。

 なお、Entryコントロールにおいて、Textプロパティを、空白("")で初期化しているのが一見無駄に見えるが、これが無いと、起動時にデータトリガーが機能せず、Buttonコントロールが無効とならないため省略することはできない。

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

図5 データトリガーの実行画面(Android/iOS)

Entryコントロールに、何らかの入力があるときだけ、Buttonコントロールが有効になる

6. イベントトリガー

 イベントトリガーを使用するには、MainPage.xamlファイルを以下のように修正する。

XAML
 1
 2
 3
1
 5
 6
 7
2
 9
3
4
12
13
14
15
16
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:TriggerSample;assembly=TriggerSample"
             x:Class="TriggerSample.MainPage">

  <StackLayout Padding="20">
    <Entry Placeholder="Age">
      <Entry.Triggers> 
        <EventTrigger Event="TextChanged">
            <local:EntryValidation />
        </EventTrigger>
      </Entry.Triggers>
    </Entry>
  </StackLayout>
</ContentPage>
イベントトリガーを実装したXAML(MainPage.xaml)

 StackLayoutには、Entryコントロールを一つだけ配置し、年齢の入力を促すため、PlaceholderプロパティにAgeと指定した(2)。

 そして、Triggersプロパティに対して、テキストの変換(TextChangedイベント)で動作するイベントトリガーを設定した(3)。

 トリガーの動作は、EntryValidationクラスに定義することとし(4)、このクラスのアセンブリ上の位置を指定しした(1)。

 続いて、そのEntryValidationクラスを定義するため、App.csファイルを以下のように修正する。

C#
……省略……
namespace TriggerSample {
  
  ……省略……

  public class EntryValidation : TriggerAction<Entry> { // <- 1
    protected override void Invoke(Entry sender) { // <- 2
      int n;
      if (!Int32.TryParse(sender.Text, out n)) { // <- 3
        sender.TextColor = Color.Red;
      } else {
        sender.TextColor = Color.Blue;
      }
    }
  }

}
EntryValidationクラスを定義したコード(App.cs)

 EntryValidationクラスは、TriggerActionクラスを継承して定義する(1)。

 Invokeメソッドをオーバーライドすることで(2)、その動作を定義できるが、ここでは、入力内容が数値として有効な場合にテキストの色を青色とし、無効のときは、赤色となるようにした(3)。

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

図6 イベントトリガーの実行画面(Android/iOS)

数値以外の入力があると、テキスト色が赤色になる

7. マルチトリガー

 マルチトリガーを使用するには、MainPage.xamlファイルを以下のように修正する。

XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="TriggerSample.MainPage">
  <StackLayout Padding="20">
    <Entry Text="" Placeholder="email" x:Name="email"/> <!-- 1 -->
    <Entry Text="" Placeholder="phone" x:Name="phone"/> <!-- 2 -->
    <Button Text="OK"> <!-- 3 -->
      <Button.Triggers>
        <MultiTrigger TargetType="Button">
          <MultiTrigger.Conditions>
            <BindingCondition Binding="{Binding Source={x:Reference email},Path=Text.Length}" Value="0" /> <!-- 4 -->
            <BindingCondition Binding="{Binding Source={x:Reference phone},Path=Text.Length}" Value="0" /> <!-- 5 -->
          </MultiTrigger.Conditions>
          <Setter Property="IsEnabled" Value="False" /> <!-- 6 -->
        </MultiTrigger>
      </Button.Triggers>
    </Button>
  </StackLayout>
</ContentPage>
イベントトリガーを実装したXAMLコード(MainPage.xaml)

 StackLayoutには、2つのEntryコントロールと(12)、Buttonコントロール(3)を配置した。

 そして、ButtonコントロールのTriggersプロパティには、マルチトリガーが指定されており、2つのEntryコントロールのテキストサイズが両方とも0のときだけ(45)、自身のIsEnabledプロパティがFalseになるようになっている(6)。

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

図7 マルチトリガーの実行画面(Android/iOS)

2つのEntryコントロールが両方とも空白のときだけ、Buttonコントロールが無効になる

8. まとめ

 今回は、各種のトリガーの実装方法について解説した。

 トリガーは、以前に紹介したビヘイビアーと同じような目的で利用可能であるが、簡単な動作であれば、より簡単にXAMLだけで書けるという点では軍配が上がりそうだ。

 トリガーやビヘイビアーをうまく使いこなして、よりユーザーに優しいUI構築を目指してほしい。

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

43. MvvmCrossでコマンドバインディングをするには?

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

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

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

45. 【現在、表示中】≫ Xamarin.Formsでトリガーを使用するには?

イベントやプロパティの変化に応じたコントロールの外観の変更をXAMLだけで実装できるトリガーの基本的な使用方法を解説する。

46. Xamarin.FormsでWebビューを使用するには?

外部のWebページやローカルに配置されたHTMLコンテンツを簡単に表示できるWebViewコントロールをXamarin.Formsで使う方法を説明する。

47. MvvmCrossで画面遷移するには?

MvvmCrossでiOS/Androidアプリの画面遷移をするための基本的な実装方法を説明する。

Twitterでつぶやこう!


Build Insider賛同企業・団体

Build Insiderは、以下の企業・団体の支援を受けて活動しています(募集概要)。

ゴールドレベル

  • 日本マイクロソフト株式会社
  • グレープシティ株式会社