TIPS例えば検索画面で、検索文字列を1文字入力するごとに検索結果の表示を絞り込んでいきたい場合など、テキストボックスに入力中の文字列をバインド元に反映させて処理する方法を説明する。検索する画面で、検索文字列を1文字入力するごとに検索結果の表示を絞り込んでいきたい場合などだ。8)のWindowsストアアプリでは、それはバインディングでは実現できなかった。8.1)での新しい方法を2通り紹介する。8.1版)」からダウンロードできる。2013)が必要である。Windows(日本語版)*1を使用している。Windows」から無償で入手できる。ベースとなるプログラムを用意するこれから行う実験のベースとなるプログラムを作っておく。本稿ではXAMLコードの詳しい説明は省略させていただくので、次の画像を参考にして適宜UIを構築してほしい。サンプルコードを実行している画面これは、別途公開しているサンプルコードを実行したときの画面である。8のときの方法で実装してある。1段目の入力欄に文字列を入力している最中は、2段目のバインドしたテキストボックスには反映されない(入力欄からフォーカスを移動したタイミングで反映される)。3段目のテキストボックスの内容は、1段目の入力欄のTextChangedイベントで書き換えている。8.1で追加された方法を使う(最下段のトグルスイッチをオンにする)と、イベントハンドラー内で強制的にバインディングソースへ変更を反映できるので、2段目のテキストボックスにも1文字入力するごとに反映されるようになる。8.1で新しく追加された方法で実装した。上段の入力欄に文字列を入力している最中に、下段のバインドしたテキストボックスに反映される。ベースとなるプログラムでは、バインディングソースとなるstringオブジェクトを用意し、TextBoxコントロール(Windows.UI.Xaml.Controls名前空間)をそれにバインドする(次の図)。stringオブジェクトとTextBoxコントロールをバインドする一方のTextBoxコントロールは双方向バインディングとし、他方は単方向バインディングとする。これにより、上の[入力]というヘッダーが付けてあるTextBoxコントロールに文字列を入力すると、下の[バインド]というヘッダーを付けたTextBoxコントロールに反映されるはずである。実装は以下のように進める。(XAML)]を選ぶ。出来上がったプロジェクトから「MainPage.xaml」ファイルを削除し、あらためて[基本ページ]を「MainPage.xaml」ファイルとして追加する。これにより、プロジェクトにCommonフォルダーとその中にソースコードが幾つか自動生成される。これは、以降でデータバインディングの実装を簡単に行うために必要だ。次に、「MainPage.xaml」ファイルにTextBoxコントロールを2つ配置し、データバインディングを設定する(次のコード)。/>データバインディングを設定したTextBoxコントロール(XAML)上のTextBoxコントロールは双方向バインディング、下は単方向バインディングだ。バインディングソースに指定している「SampleText1」は、次に説明する。別途公開しているサンプルコードでは、このコードは画面左側の1段目と2段目のTextBoxコントロールに当たる。最後に、コードビハインドでバインディングソースの初期値を設定しておく(次のコード)。Sub文字列の初期値をDefaultViewModelオブジェクトにセットするコード(上:C#、下:VB)太字の部分を追加する。「SampleText1」というキーで文字列をセットした。これで実行してみると、[入力]欄に入力している最中には[バインド]欄に反映されないことが確認できる。TextBoxコントロールとのデータバインドでは、1文字入力するごとにはバインディングソースへ反映されないのだ。[入力]欄からフォーカスを移動したときだけ反映されるのである。8では、1文字入力するごとに処理するには、以下のようにしてTextChangedイベントでロジックを呼び出すしかなかった。データバインディングはあきらめて、入力用のTextBoxコントロールにはTextChangedイベントを追加し、出力用のTextBoxコントロールには名前を付ける(次のコード)。/>TextChangedイベントを設定したTextBoxコントロール(XAML)太字の部分を追加した。別途公開しているサンプルコードでは、このコードは画面左側の1段目と3段目のTextBoxコントロールに当たる。サンプルコードでは、データバインディングの設定を残している(ここでは不要なのだが、次に説明する方法では必要になる)。次に、イベントハンドラーでロジックを呼び出して、結果を出力用のTextBoxコントロールに書き出すようにする(次のコード)。Sub入力文字列が変化したときのイベントハンドラー(上:C#、下:VB)これで実行してみると、確かに1文字入力するごとに反映される。実際に開発する場面を考えてみると、他のところではデータバインディングで画面とロジックをつないでいるのに、テキストボックスだけはコードビハインドからロジックを呼び出すというのでは、画面とロジックのインターフェースがバラバラである。8.1では、この問題は簡単に解決できるようになった。8.1では、新設されたBindingExpressionクラス(Windows.UI.Xaml.Data名前空間)を使うことで、コントロールの内容を強制的にバインディングソースへ反映できるようになった。最初のXAMLコードに対して、データバインディングを残したままで、入力用のTextBoxコントロールにTextChangedイベントを追加する(次のコード)。/>イベントを追加したTextBoxコントロール(XAML)入力用のTextBoxコントロールにTextChangedイベントを追加した(太字の部分。追加する内容自体は上で示したXAMLと同様である)。別途公開しているサンプルコードでは、このコードは画面左側の1段目と2段目のTextBoxコントロールに当たる。[入力]用のTextBoxコントロールの内容をイベントハンドラーで強制的にバインディングソースへ反映させるようにするのだ(次のコード)。Sub入力文字列が変化したときのイベントハンドラー(上:C#、下:VB)別途公開しているサンプルコードでは、トグルスイッチによってこの処理をオン/オフできるようにしている。これでTextBoxコントロールに1文字入力するごとに、その内容がバインディングソース(を介してバインディング先のコントロール)に反映されるようになるので、確かめてほしい。この方法で画面とロジックのインターフェースをデータバインディングに統一できるのだが、実際には次に説明する方法の方が簡単だ。このBindingExpressionを使って強制的にバインディングソースへ反映させる方法は、むしろユーザーアクション(ボタンのタップなど)に基づいてバインディングソースへ反映させたいときに有効である。8.1でBindingクラス(Windows.UI.Xaml.Data名前空間)に追加されたUpdateSourceTriggerプロパティを使えば、イベントに頼らずに済むようになる。このプロパティに「PropertyChanged」と設定するだけである(次のコード)。/>バインディングにUpdateSourceTriggerプロパティを追加したTextBoxコントロール(XAML)最初のコードに太字の部分を追加する(TextChangedイベントは付けない)。別途公開しているサンプルコードでは、このコードは画面右側の1段目と2段目のTextBoxコントロールに当たる。サンプルコードでは、バインディングソースを「SampleText1」から「SampleText2」に変えている。UpdateSourceTriggerプロパティの既定値は「Default」であり、その動作はMSDNには「PropertyChangedの値と同じ値として評価されます」と記述されているが、TextBoxコントロールにおいては誤りである。TextBoxコントロールのバインディングで「Default」を指定すると、WPFで「LostFocus」を指定したときと同じ動作(=フォーカスを失ったときに反映)になる(ただし、WindowsストアアプリのUpdateSourceTriggerプロパティには「LostFocus」を指定できない)。8.1でテキストボックスに入力中の文字列をバインディングソースに反映させるには、バインディングの指定に「UpdateSourceTrigger=PropertyChanged」を追加すればよい。ユーザーアクションのタイミングでバインディングソースへ反映させるには、BindingExpressionクラスを利用する。BindingExpressionクラスについては、次のドキュメントも参照してほしい。MethodUpdateSourceTriggerプロパティについては、次のドキュメントも参照してほしい。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。