 
Xamarin逆引きTips
Xamarin.Formsでトリガーを使用するには?
イベントやプロパティの変化に応じたコントロールの外観の変更をXAMLだけで実装できるトリガーの基本的な使用方法を解説する。
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)。
続いて、ソリューションエクスプローラーのPCL(共通プロジェクト)で右クリックして表示されるメニューから[追加]-[新しい項目]を選択し、表示されたダイアログで[インストール済み]-[Visual C#]-[Forms Xaml Page]を選択し、名前を「MainPage.cs」として[OK]ボタンを押す(図2)。
作成したXAMLページ(MainPage)をアプリの最初のページにするためには、App.csファイルを以下のように修正する。
| using Xamarin.Forms; namespace TriggerSample {   public class App : Application {     public App(){       MainPage = new MainPage();     }     ……省略……   } } | 
3. プロパティトリガー
プロパティトリガーを使用するには、MainPage.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> | 
 StackLayoutの中に、Entryコントロールを1つ配置し(1)、Triggersプロパティを指定した(2)。
 トリガーは、IsFocusedプロパティがTrueとなったときに(3)、BackgroundColorプロパティが水色(Aqua)になるように指定している(4)。
このコードを実行すると次のような画面になる。
4. ページ全体のトリガー
トリガーは、個々のコントロールに指定するだけでなく、ページのリソースに定義して、ページ全体に影響させることもできる。ページ全体のトリガーを指定するには、MainPage.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> | 
 ページのリソースとして(1)、Entryコントロールに適用されるスタイルを定義する(2)。
 トリガーは、先ほどと同じで、IsFocusedプロパティがTrueとなったときに(3)、BackgroundColorプロパティが、今度は黄色(Yellow)になるように指定した(4)。
 ここまでの定義が終わると、このページ内で使用する全てのEntryコントロールに、このトリガーが適用されることになる(56)。
このコードを実行すると次のような画面になる。
5. データトリガー
データトリガーを使用するには、MainPage.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> | 
 StackLayoutの中に、Entryコントロールと(1)、Buttonコントロールを配置した(2)。
 ButtonコントロールのTriggersプロパティには、データトリガーが指定されており、EntryコントロールのTextプロパティのサイズが0のとき(3)、自身のIsEnabledプロパティがFalseとなるようになっている(4)。
 なお、Entryコントロールにおいて、Textプロパティを、空白("")で初期化しているのが一見無駄に見えるが、これが無いと、起動時にデータトリガーが機能せず、Buttonコントロールが無効とならないため省略することはできない。
このコードを実行すると次のような画面になる。
6. イベントトリガー
イベントトリガーを使用するには、MainPage.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> | 
 StackLayoutには、Entryコントロールを一つだけ配置し、年齢の入力を促すため、PlaceholderプロパティにAgeと指定した(2)。
 そして、Triggersプロパティに対して、テキストの変換(TextChangedイベント)で動作するイベントトリガーを設定した(3)。
 トリガーの動作は、EntryValidationクラスに定義することとし(4)、このクラスのアセンブリ上の位置を指定しした(1)。
 続いて、そのEntryValidationクラスを定義するため、App.csファイルを以下のように修正する。
| ……省略…… 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クラスは、TriggerActionクラスを継承して定義する(1)。
 Invokeメソッドをオーバーライドすることで(2)、その動作を定義できるが、ここでは、入力内容が数値として有効な場合にテキストの色を青色とし、無効のときは、赤色となるようにした(3)。
このコードを実行すると次のような画面になる。
7. マルチトリガー
マルチトリガーを使用するには、MainPage.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> | 
 StackLayoutには、2つのEntryコントロールと(12)、Buttonコントロール(3)を配置した。
 そして、ButtonコントロールのTriggersプロパティには、マルチトリガーが指定されており、2つのEntryコントロールのテキストサイズが両方とも0のときだけ(45)、自身のIsEnabledプロパティがFalseになるようになっている(6)。
このコードを実行すると次のような画面になる。
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で使う方法を説明する。





 
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 
