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で使う方法を説明する。