サンプル2~イベントのハンドリング
では、続いてコントロールに対するイベントのハンドリングを行ってみましょう。
ボタンコントロールを配置し、ダブルクリックすると、イベントハンドラ記述のためのコードウィンドウへと切り替わります。コードウィンドウに次のように、ラベルに文字列を表示するコードを入力します。
private void button1_Click(object sender, RoutedEventArgs e) { label1.Content = "ボタンが押されました"; }
これまでのWindows Formsの場合と同じく、XAMLコード内に配置されている要素は、ソースコードからオブジェクトとしてアクセスすることができます。ラベルの文字列はサンプル1で見たとおり、Content
プロパティで設定します。
このときのXAMLコードは次のようになっています。
<Grid> <Label Height="28" Margin="66,89,92,0" Name="label1"
VerticalAlignment="Top" Content="Hello WPF World !"></Label> <Button Height="23" Margin="94,0,109,63" Name="button1"
VerticalAlignment="Bottom" Click="button1_Click"> Button</Button> </Grid>
Button要素のClick
属性に、イベントハンドラであるbutton1_Click
メソッドが指定されていることが分かります。
XAMLでは、イベント名の属性を作成し、イベントハンドラとなるメソッド名を指定することで、イベントのバインドが行われます。
[F5]キーを押してサンプルを実行し、イベントハンドラがきちんと動作していることを確認しましょう。
ボタンをクリックするとラベルの内容が変化します。
コードビハインド
イベントハンドラのコードは、C#の場合はXAMLファイル名の末尾に.csを付加したファイルに記述します(VBの場合は末尾に.vbを付加したファイル)。
このC#(あるいはVB)のファイルをコードビハインド ファイルと呼びます。このプロジェクトの場合は「Window1.xaml.cs」がコードビハインド ファイルです。
XAML側で定義したコントロールはコードビハインド側のコードから、同じクラスのメンバとしてアクセスすることができます。これはコードビハインドのコードが部分(partial)
クラスでXAMLコードと同じクラスとして定義されているためです。
実際には、コードビハインド ファイルの他に、XAMLのコントロールをメンバとして定義するファイルが内部的に自動生成されています。
コードウィンドウの右上のメンバ一覧から、label1などのXAMLのコントロールを選択することで、自動生成されたコードを確認することができます。
public partial class Window1 : System.Windows.Window, System.Windows.Markup.IComponentConnector { #line 6 "..\..\Window1.xaml" internal System.Windows.Controls.Label label1; #line default #line hidden #line 7 "..\..\Window1.xaml" internal System.Windows.Controls.Button button1;
XAMLで定義されたlabel1やbutton1といったコントロールが、部分クラス内にメンバとして定義されていることが確認できます。これによって、イベントハンドラ内でコントロールへのアクセスが可能となっています。
なお、このファイルの先頭のコメントにも記されていますが、誤動作を避けるため、自動生成されたファイルの内容は編集しないようにしましょう。
WPFで採用しているユーザーインターフェイスをXML形式のファイルで記述し、イベントハンドラをコードビハインド ファイルに記述する、という方式ですが、実は、ASP.NETで以前から類似の方式(.aspxと.aspx.cs/.vbの関係)が用いられています。ASP.NET経験者には理解しやすい構造と言えるでしょう。従って、デザインとプログラムの分離という面でもASP.NETと同様のメリットを享受することになります。
サンプル3~ダブルクリック以外でのイベントのバインド
さて、XAMLコントロールのプロパティウィンドウを見ると、これまでのWindows Formsのコントロールのプロパティウィンドウとはちょっと異なることに気付きます。
全般的な雰囲気が違うのはもちろんですが、特にWindows Formsコントロールで表示されている、イベントを扱うための雷アイコンが、XAMLコントロールでは表示されていないことに注目してください。
先ほどのサンプルでは、ボタンをダブルクリックした場合には自動的にClickイベントのバインド行われました。Visual Studio 2008では、これまでのバージョンと同様に、コントロールをダブルクリックした場合には、各コントロールの代表的なイベントについてのバインドが行われます。
では、他のイベントについてはサポートされていないのか? と言うと、そういうわけではありません。
ここでは、ダブルクリックでバインドされないイベントについて、Visual Studio 2008でどう記述するかを確認しましょう。
先ほど見たとおりXAMLでは、イベントに対応する属性を作成し、イベントハンドラのメソッド名を記述することでイベントのバインドを行うことができます。しかし、自分でこうしたコードをすべて記述するのはミスしやすいですし、定型の内容を毎回手動で入力するというのは無駄に感じます。
Visual Studio 2008では、ダブルクリックでバインドされないイベントについても、IntelliSenseを使用することで、簡単にイベントハンドラの作成を行うことができます。
先ほどのサンプルで、ボタン上にマウスカーソルが入った場合(MouseMoveイベント)と、マウスカーソルが出て行った場合(MouseLeaveイベント)の2イベントをハンドリングしてみましょう。
XAMLコードのButton
要素の開始タグ内でスペースキーを押すと、IntelliSenseが働き、そこに記述可能な属性の一覧が表示されます。ここで、一覧からMouseMoveイベントを選択しましょう。
イベントを選択すると、新しいイベントハンドラを作成するかどうか、メッセージが表示されますので、そのまま[Enter]キーを押します。
新しいイベントハンドラが作成され、属性にセットされます。
<Button Height="23" Margin="94,0,109,63" Name="button1"
VerticalAlignment="Bottom" Click="button1_Click"
MouseMove="button1_MouseMove">Button</Button>
MouseMove
属性の上で右クリックし、メニューから[イベント ハンドラへ移動]を選択すると、コードビハインド ファイルに作成されたイベントハンドラに移動することができます。
同様に、MouseLeaveイベントも作成しましょう。今回はイベントハンドラとして、新たに作成するか、既にあるbutton1_MouseMove
メソッドをバインドするかを尋ねてきますので、<新しいイベント ハンドラ>を選択しましょう。
MouseLeave
属性の上で右クリックし、メニューから[イベント ハンドラへ移動]を選択し、次のようにイベントハンドラを記述しましょう。
private void button1_MouseMove(object sender, MouseEventArgs e) { label1.Content = "マウスカーソル進入"; } private void button1_MouseLeave(object sender, MouseEventArgs e) { label1.Content = "マウスカーソル通過"; }
この状態でのXAMLコードは次のとおりです。
<Button Height="23" Margin="94,0,109,63" Name="button1"
VerticalAlignment="Bottom" Click="button1_Click"
MouseMove="button1_MouseMove"
MouseLeave="button1_MouseLeave">Button</Button>
[F5]キーを押して実行すると、マウスカーソルがボタン内に入った場合、外に出た場合でラベルの文字列が変化することを確認できます。
このように、ダブルクリックでバインドされないイベントについても、IntelliSenseのサポートにより、簡単にバインドを行うことができます。
以上で作成したサンプルは、サンプルファイルのWpfTestプロジェクト内に含まれています。