前回は簡単にバインディングができることを確認しました。実はあれは省略形に近いものだったので、フルに設定するとどのようになるかを今回確認します。基本的に前回のプロジェクトの使い回しで説明します。
メソッド呼び出し
ボタンの Name を削除して、 Interaction.Triggers を指定してメソッドを呼び出してみます。ShellView.xaml は以下のように変更します。
<Grid>
<TextBlock Name="Count"
FontSize="80"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<Button FontSize="20"
Content="Increment"
VerticalAlignment="Bottom"
HorizontalAlignment="Center"
Margin="20">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="IncrementCount"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
EventTrigger の Click までは問題ないとして、 Livet では CallMethodAction を呼び出していたような箇所で、 ActionMessage によってメソッドを呼び出します。この ActionMessage も引数情報を設定することが可能です。パラメータを指定するには以下のようにします。
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="IncrementCount">
<cal:Parameter Value="5"/>
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
これを受け取るための IncrementCount メソッドでは引数を取れるように変更する必要があります。忘れると例外(No target found for method IncrementCount.)が飛びます。
メソッド呼び出し その2
ここまでの設定方法が Long Syntax と呼ばれるものになっているようです。次に Short Syntax と呼ばれるものについて確認してみます。
ShellView.xaml を編集してボタンを追加してみます。
<Grid>
<UniformGrid VerticalAlignment="Bottom"
Columns="2">
<Button Content="+2" Margin="15" cal:Message.Attach="[Event Click] = [Action IncrementCount(2)]"/>
<Button Content="+5" Margin="15" cal:Message.Attach="[Event Click] = [Action IncrementCount(5)]"/>
</UniformGrid>
<TextBlock Name="Count"
FontSize="80"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Grid>
見て分かるように、 cal:Message.Attach という添付プロパティでイベントとアクション(メソッド呼び出し)を設定しています。 注目なのはイベント名の記述と、メソッドの呼び出し&引数記述がこのように書ける、という点です。わかりやすいですね。
引数については即値で書いていますが、ここを他のコントロールの値にすることも可能です。
cal:Message.Attach="[Event Click] = [Action IncrementCount(Count.Text)]"
さらに Caliburn では、メソッド引数名から、引数を推測してバインディングしてくれる機能もあります。以下のように ShellView.xaml を編集して、スライダとボタンを用意してみます。
<Grid>
<UniformGrid VerticalAlignment="Bottom"
Columns="2">
<Button Content="+2" Margin="15" cal:Message.Attach="[Event Click] = [Action IncrementCount(2)]"/>
<Button Content="+5" Margin="15" cal:Message.Attach="[Event Click] = [Action IncrementCount(5)]"/>
</UniformGrid>
<UniformGrid VerticalAlignment="Top"
Columns="2">
<Slider Name="delta" Minimum="1" Maximum="10" Value="5" Margin="10"/>
<Button Content="Increment" Name="IncrementCount" Margin="15"/>
</UniformGrid>
<TextBlock Name="Count"
FontSize="80"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Grid>
スライダの名前を IncrementCount の引数名である delta としたことで、 Caliburn が情報をうまく解釈して結合してくれます。
まとめ
自分でバインディング設定を記述しないでもバインディングしてくれることで、プログラマの作業を省力化してくれる感がすごくあります。ただし、ルールを知らないと動きを追いかけるのも厳しいという印象です。
これらのバインディングについては、 All About Actions を参照して読んでおくのもよさそうです。パラメータとして、 $source, $view, $dataContext といったものも設定可能であったりするので、なかなか深いです。