連載
» 2010年05月14日 00時00分 公開

連載:WPF入門:第1回 いよいよWPFの時代。WPFの習得を始めよう (2/3)

[岩永信之(http://ufcpp.net),著]

ツリー構造のUI要素

 Figure 3に模式的に表すように、WPFのUI要素はツリー構造により構築される。

Figure 3: ツリー構造のUI要素

 この例では、Canvas要素を入れ子にしているが、WPFではボタンなどのコントロールの中身も入れ子にすることができる。例えば、ボタンの中に動画を配置したり、コンボボックスの中にボタンを並べたりすることも可能だ。

 このようなWPFのツリー構造のUI要素では、要素の親子関係によって以下のようなことが起こる。

  • 平行移動や回転などの変形は、親要素からの相対位置に基づいて、子要素もろとも行われる
  • 添付プロパティという仕組みを用いて、要素自身ではなく、親要素が使う情報を持てる
  • FontSizeなど、一部のプロパティは親要素から値を継承する(包含継承)

 まず、Figure 4に平行移動の例を示す。また、Figure 4の平行移動に加えて、回転も掛けたものをFigure 5に示す(簡便性のため、回転に関係のないプロパティは省略)。いずれも、位置指定(Canvas.Left属性やCanvas.Top属性など)は親要素からの相対指定となっている。また、回転は子要素ともども行われていることが分かる。

Figure 4: UI要素の平行移動

Figure 5: UI要素の回転

 ここで、Figure 4の例に注目してほしい。入れ子になったCanvas要素やRectangle要素がCanvas.Top属性とCanvas.Left属性を持っていることに気付くだろう。これらの属性値は、要素自身ではなく、1段上の親に当たるCanvas要素が使用する。この親Canvas要素は、座標を指定して任意の位置に子要素を配置するためのコンテナだが、その子要素の座標指定は子要素にCanvas.Left属性とCanvas.Top属性を付与することで行う。

 このような、自分自身ではなく、親要素が使用する値を子要素に付与するための仕組みを「添付プロパティ」(Attached Property)と呼ぶ。通常の意味での(つまり.NETのクラスの)プロパティでは、この仕組みを素直に実現することはできない。

 もちろん、すべてのUI要素がLeftプロパティおよびTopプロパティを持つことでも可能ではあるが、そうしてしまうと、Canvas要素を利用しない場合に無駄なデータを持つことになってしまう。そこでWPFでは、添付プロパティや後述するデータ・バインディングを実現するための機能として「依存関係プロパティ」(Dependency Property)という仕組みを持っている。依存関係プロパティの詳細については次回以降で説明することになるが、簡単にいうと、一種の辞書構造を用いて値を保持する仕組みである。

 さて、最後に、値の包含継承について説明しておこう。HTMLコードを書いたことがある人ならご存じであろうが、HTMLでは親要素に書いた属性値が子要素に継承されることがある。例えば、body要素に対してstyle属性やfont属性でフォント・サイズを指定すると、body要素内のすべての要素のフォント・サイズが変化する。

 WPFでもこのような仕組みを採用しており、FontSizeプロパティなど、一部のプロパティ値を(プロパティ定義時の指定次第で)親要素から継承するようになっている。オブジェクト指向における「継承」(=クラスの継承)と区別するために、これを「包含継承」と呼ぶ。

データ・バインディング

 WPFでは、ビュー(=データの表示)とモデル(=データの不整合がないかの検証や、データベースなどへのデータの永続化)を分離するための仕組みとして、データ・バインディングという機能を提供している。データ・バインディングでは、ビュー側には「ここにこのデータを表示したい」というような目印だけを入れ、 実際のデータは外部から与えることになる。

Figure 6: データ・バインディングの例

 Figure 6に例示するように、XAMLコード内で、属性値に「{Binding}」という記述を行う。実際に表示したいデータは、DataContextというプロパティを介して渡すことになる。例えば、上記の例の場合、DataContextプロパティに渡されたPoint型データのXプロパティとYプロパティの値を、Button要素のContent属性に結び付ける。値の結び付けはリフレクションを用いて行われており、DataContextには任意の型を渡すことができる。

 この仕組みをうまく利用すれば、ビューとモデルの接点はDataContextプロパティのただ1点のみとなり、疎結合が実現できる。また、ビューの内部には一切ロジックを持つ必要がない(すなわち、ビューの分離コード内にはロジック用のコードを一切書かない)。

 詳細は次回以降の説明となるが、モデル側で、データの更新通知や、ユーザーから入力されたデータの妥当性検証を行う仕組みが提供されている(INotifyPropertyChangedインターフェイスや依存関係プロパティという仕組みなどを用いる)。

 Figure 7にデータの更新通知の例を示す。この例では、XやYの値はテキストボックスとスライダ・コントロールで共有されていて、片方の値が変更されると即座に他方に値の変更が通知され、ビューに変更が反映される。また、XとYの値の変化と連動して、X+Yの値の変化も即座にビューに反映される。

Figure 7: データの更新通知の例

 次のページでは、WPFのUI要素を紹介する。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。