コレクション
一部のオブジェクトは、複数の子オブジェクトを保有する性質を持ちます。任意の数のオブジェクトを保有する性質をもつオブジェクトのことをコレクションと呼び、コレクションはオブジェクの列を管理する機能を提供します。
代表的なコレクションを持つオブジェクトはCanvasオブジェクトです。これまで表示した楕円やテキストは、XAMLのルート要素として指定してきましたが、複数のオブジェクトを表示するためにトップレベルの要素を複数書くことはできません。XMLは、複数のルート要素を許していないためです。複数のオブジェクトを表示するには、何らかの親要素の子として管理しなければなりません。
Canvasは、こうした表示可能なオブジェクトの入れ物となるオブジェクトです。Canvasは、子要素にEllipseやTextBlockのような表示可能なオブジェクトを任意の数だけ指定できます。このような、任意の数のオブジェクトを内部で管理する機能を持つコレクションにXAMLから子オブジェクトを設定するには、通常は直接の子要素として指定します。例えばCanvasオブジェクトにEllipseとTextBlockオブジェクトを表示させるにはCanvas要素の子要素としてEllipse要素とTextBlock要素を指定します。
<Canvas xmlns="http://schemas.microsoft.com/client/2007"> <Ellipse Fill="Pink" Width="200" Height="100" /> <TextBlock>Silverlight!</TextBlock> </Canvas>
サンプル 04を実行すると、楕円形とテキストが同時に表示されていることが確認できます。
実際には、Canvas要素の子要素に指定されたオブジェクトは、CanvasオブジェクトのChildrenプロパティに対応しています。Childrenプロパティは、Canvasオブジェクトが管理している表示可能なオブジェクトのコレクションを表すVisualCollectionオブジェクトを返します。スクリプトから動的に子オブジェクトを制御する場合は、Childrenプロパティを用いる必要がありますが、XAMLからは必要ありません。直接Canvas要素の子要素としてオブジェクトを設定することができます。
Silverlight用のXAMLでは、VisualCollectionを明示的に宣言できないため、CanvasオブジェクトのChildrenプロパティをXAMLから直接指定することはありません。上記のサンプルのように、直接子要素として設定できます。しかし、中にはコレクションを明示的にXAMLから宣言することができるオブジェクトも存在します。例えば、グラデーションで図形の内部を塗りつぶすLinearGradientBrushオブジェクトを作成する場合、変化する色を表すGradientStopオブジェクトのコレクションを、LinearGradientBrushオブジェクトのGradientStopsプロパティが返すGradientStopCollectionに設定しなければなりません。
Silverlight用のXAMLは、GradientStopCollection要素を用いてコレクションを作成することを許容しています。そのためLinearGradientBrush要素の子要素としてLinearGradientBrush.GradientStopsプロパティ要素を指定し、この中にGradientStopCollection要素としてコレクションを宣言できます。長方形を表すRectangleオブジェクトを用いて、内部をグラデーションで塗りつぶす場合は次のようになります。
<Rectangle
xmlns="http://schemas.microsoft.com/client/2007"
Width="400" Height="300"
> <Rectangle.Fill> <LinearGradientBrush StartPoint="0.5, 0" EndPoint="0.5, 1"> <LinearGradientBrush.GradientStops> <GradientStopCollection> <GradientStop Offset="0.0" Color="Blue" /> <GradientStop Offset="1.0" Color="White" /> </GradientStopCollection> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Fill> </Rectangle>
しかし、実際にはこのような複雑なXAMLを書く必要はありません。Canvasオブジェクトの場合と同じように、プロパティを明示しなくても自動的に子要素をコレクションとして判断し、適切なプロパティに設定してくれる仕組みが用意されています。LinearGradientBrush.GradientStopsプロパティ要素はGradientStopCollection子要素を省略し、直接の子として任意の数のGradientStop要素を指定しても適切に扱ってくれます。さらに、LinearGradientBrush要素も、LinearGradientBrush.GradientStopsプロパティ要素を省略してGradientStop子要素を指定することを許可しています。
このような、子オブジェクトのコレクションを保持するプロパティの設定で、コレクションの宣言などを省略する仕組は暗黙的なコレクションと呼ばれます。最終的に、サンプル 05は次のように簡略化できます。
<Rectangle
xmlns="http://schemas.microsoft.com/client/2007"
Width="400" Height="300"
> <Rectangle.Fill> <LinearGradientBrush StartPoint="0.5, 0" EndPoint="0.5, 1"> <GradientStop Offset="0.0" Color="Red" /> <GradientStop Offset="1.0" Color="Black" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle>
サンプル 06の場合は、グラデーションの色を表すGradientStop要素をLinearGradientBrush要素の直接の子要素として指定しています。この場合でも、Silverlightは適切に意味を理解してGradientStopsプロパティのGradientStopCollectionオブジェクトとして任意の数のGradientStopオブジェクトを設定してくれます。
暗黙的なコレクションの構文はすべてに共通するものではないため、個別にはリファレンスを確認する必要があります。しかし、オブジェクトやプロパティの役割が何らかの子オブジェクトの入れ物となる場合、暗黙的なコレクションをサポートしていると考えてよいでしょう。
最後に
さて、本稿ではSilverlightをブラウザ上で表示する方法とXAMLの基本的な文法を説明させていただきました。Silverlightアプリケーション開発においてXAMLは描画するオブジェクトを宣言する重要な仕組みとなっています。XAMLは、同じようにXMLによって記述されるSVGのようなベクタグラフィックス言語とは性質が異なり、図の宣言だけではなく、アプリケーションによって生成されるオブジェクトの宣言を目的としています。XAMLで書かれるコードは、実行環境のオブジェクトに直接対応しているためプログラムを意識したものとなるでしょう。
本稿ではXAMLの書き方を中心に解説しましたが、Silverlightで自由に図やイメージを描画するにはSilverlightが提供しているオブジェクトの種類とその性質を正しく理解する必要があります。表示したオブジェクトをスクリプトから制御するためにも、オブジェクトの性質を知ることは重要です。次回は、さまざまなSilverlightオブジェクトをXAMLで記述して表示する方法を解説いたします。
