SilverlightおよびWPFの基本的な設計の最終目的は、開発者がUI機能を再利用可能なコントロールに簡単にカプセル化できるようにすることです。
既存のコントロールクラス(コントロールベースクラスまたはTextBoxやButtonなどの様なコントロール)からクラスを派生させて新しく固有のコントロールを実装することができます。または、再利用可能なユーザコントロールを作成することができます。これによりコントロールのUIを作成するXAMLタグファイルの使用が簡単になります。(また非常に簡単にビルドできるようになります。)
Digg.comチュートリアルのパート 6では、VS 2008で"新しい項目..."のダイアログを使用して新規のユーザコントロールを作成し、その中でUIを定義する方法をご覧いただきました。この方法はユーザコントロールでUIをカプセル化したいページが分かっている場合には非常に有効です。この同じテクニックをExpression Blendでも使用することができます。
既存のUIをユーザコントロールとしてカプセル化
場合によっては、親ページやコントロールを定義し始めるまでどのUI機能を再利用可能なユーザコントロールとしてカプセル化すればいいのか分からないことがあります。
例えば、ユーザが出荷および請求情報を入力できるようなフォームを作成しているとします。まず住所入力をカプセル化するUIを作成します。これをするには、<border> コントロールをページに追加し、その中にグリッドレイアウトパネルをネストし(2つの列と4つの行を使用)、その中にラベルとテキストボックスを設置します。
:
全てきっちりレイアウトした後に、"請求書の宛先にも全く同じUIを使用するんだから、再利用可能な住所ユーザコントロールを作成すれば繰り返さなくてもよくなるのでは。" と気づいたりします。
"新しい項目..." プロジェクトテンプレートの方法で新しくユーザコントロールを作成して、上記のUIコンテンツをその中にコピー&ペーストします。
Blendでは、もっと早い方法として、ユーザコントロールとしてカプセル化したいコントロールをデザイナで選択して、
"右クリック"し、メニューから"コントロールの作成" を選択します。
:
"コントロールの作成" を選択すると、Blendは作成しようとしている新規ユーザコントロールの名前入力をポップアップします。
:
そこで、"AddressUserControl" と入力し、OKをクリックします。これによりBlendは選択したコンテンツが含まれた新規のユーザコントロールを作成します。
:
プロジェクトのリビルドを行い元のページに戻ると、前と同じUIが確認できますが、その住所UIは今ではAddressUserControlの内部にカプセル化されています。
:
最初のAddressUserControl を"ShippingAddress"という名前にし、請求書の宛先用に2つ目のユーザコントロールをページに追加します。(この2つ目のコントロールインスタンスを"BillingAddress"という名前にします。)
:
もし住所の見た目を変更したい場合は、1か所で行えば出荷および請求の宛先両方に適用することができます。
AddressUserControlに住所オブジェクトをデータバインド
住所UIをカプセル化するユーザコントロールがいくつかあります。これらに対してバインドする住所のデータモデルクラスを作成していきましょう。クラスを以下の用に
(新しい自動プロパティ 言語機能を利用して)定義します。
:
Page.xamlファイルのコードビハインドファイルで、Address オブジェクトを、1つが出荷の宛先、1つが請求の宛先として、2つインスタンス化します。(このサンプルではダミーデータを紐づけます。)その後プログラムでそのAddress オブジェクトをページ上でAddressUserControls にバインドします。これは各ユーザコントロール上の"DataContext" プロパティを適切な出荷および請求の宛先データモデルのインスタンスに設定することで行えます。
最後にAddressUserControl.xamlファイルで {Binding} ステートメントを宣言し、ユーザコントロールにあるTextBoxコントロールの"Text" プロパティと、そのユーザコントロールに添付したAddressデータモデルオブジェクト上のプロパティに2方向のデータバインディング関係を設定します。
:
F5を押してアプリケーションを起動させると、AddressUserControlsでAddressデータモデルオブジェクトのデータバインドが自動的に行われます。
:
{Binding} 宣言を "Mode=TwoWay"に設定しているので、ユーザがテキストボックスを変更すると自動的にAddressデータモデルオブジェクトに返されます。(これにはコードが不要です。)
例えば、ディズニーランド宛になる様、ブラウザで元の出荷の宛先を変更することができます。
:
"保存"ボタンの "Click"イベントハンドラにデバッガのブレークポイントを置いた場合、
"_shippingAddress" データモデルオブジェクトに上記のTextBoxの変更が自動的に反映されるのを確認することができます。
:
その後、SaveBtn_Clickイベントハンドラを実装し出荷および請求のAddressデータモデルオブジェクトをお好きな様に保持するようにします。これには手動でのデータ取得やページ上のUIコントロールでの操作などは必要ではありません。
WPFおよびSilverlightがサポートしているビューとモデルの分割により、ページ上でコードを更新することなく住所のユーザコントロールを後で変更することが簡単になります。また機能の単体テストも簡単になります。
(詳細についてはSilverlight 単体テストをご覧ください。)
まとめ
WPFやSilverlightではUI機能をコントロールで簡単にカプセル化でき、それがサポートしているユーザコントロールのメカニズムによりこれを非常に簡単に利用できます。バインディングされたユーザコントロールを組み合わせると、ビューとモデルを上手く区別化でき、データを取り扱う時に非常にクリーンなコードを書くことができます。
上記のサンプルの完成版をここからダウンロードすることができますので、ご自分のマシンでお試し頂けます。
SilverlightおよびWPFについては、
Silverlight チュートリアルとリンクのページもご確認ください。また、
Karen Corbyの MIX08 でのお話(ユーザコントロール、カスタムコントロール、スタイル、コントロールテンプレートなどについて)もお勧めです。これはオンラインで
ここからご覧頂けます。
Hope this helps,
Scott