TabControlでの画像の切り替えとRichTextBoxの利用

2010年8月25日(水)
PROJECT KySS

TabControlのタブから選択された画像を、アニメーションで表示する

今回は、2つのサンプルを紹介します。1つは、XMLファイルからTabControlのタブに表示する文字列を読み取って表示し、選択されたタブに該当する画像とコメントをアニメーションで表示するものです。もう1つは、RichTextBox内に入力した文字のサイズや色を変化させ、任意の位置に画像をレイアウトするものです。

まずは、TabControlのサンプルの紹介です。実装する機能の動作は次の通りです。

TabControlのタブに表示されているタイトル名をクリックすると、画像がアニメーションを伴って切り替わります(図1)。

図1: タブをクリックして画像がアニメーションを伴って切り替わっている

サンプル・ファイルはこちらからダウンロードできます。

VS 2010のデザイン画面上で、コントロールをレイアウトする

これまでのサンプル作成時と同様の手順で、新規Silverlight 4プロジェクト(プロジェクト名は「SL4_TabControl」)を作成してください。プロジェクトの依存関係も設定してください。

次に、画像のファイル名を記録したXMLファイル(リスト1)を追加します。XMLデータはLINQ to XMLで処理するため、「プロジェクト(P) > 参照の追加(F)」からSystem.Xml.Linqを追加しておきます。

ソリューションエクスプローラ内にImageというフォルダを作成して、画像も追加しておきます。

ダウンロードされたサンプル・ファイルにはXMLファイルと画像は追加済みです。

リスト1: XML文書ファイル(photo_etc.xml)

UserControlのプロパティ内の[レイアウト]を展開して、Widthに800、Heightに600を指定します。

次にツールボックスからTextBlock、「すべてのSilverlightコントロール」からTabControlをレイアウトします(図2)。ツールボックスにTabControlコントロールが登録されていない場合は、「これからはじめるSilverlight 4」の第2回を参考に登録してください。

図2: TextBlock、TabControlをレイアウトした

書き出されるXAMLコードは省略します。

ロジックコードを記述する

ソリューションエクスプローラ内のMainPage.xamlを展開し、MainPage.xaml.vbをダブルクリックしてコード画面を開きます。

リスト2のようにロジックコードを記述します。

リスト2: ロジックコード(MainPage.xaml.vb)

LINQ to XMLでXMLを処理するクラスの含まれる、System.Xml.Linq名前空間をインポートします。ImageのSourceプロパティに画像を指定するクラスの含まれる、System.Windows.Media.Imaging名前空間をインポートします。DropShadowEffectの影を付けるのに必要なクラスの含まれる、System.Windows.Media.Effects名前空間をインポートします。

StackPanelの新しいリストとして作成するmyStackPanelArrayをメンバ変数として宣言します。

■ページが読み込まれた時の処理

XElement.LoadメソッドでXML文書ファイル(photo_etc.xml)を読み込みます。読み込んだXML文書から要素のコレクションを取得するクエリ(query)を定義します。queryを実行します。クエリコレクション内を変数resultで反復処理しながら以下の処理を実行します。

要素の値を取得し、画像名についている「.jpg」の拡張子を外したものを変数titleImageに格納しておきます。新しいStackPanelのインスタンスmyStackPanelオブジェクトを生成します。また、新しいTabItemのインスタンスmyTabItemオブジェクトを生成します。TabItemオブジェクトのHeaderプロパティに、titleImage変数を指定します。TabControlのタブに画像のタイトルが表示されます。StackPanelオブジェクトのOrientationプロパティにVerticalを指定し、子要素のスタックされる向きを垂直方向とします。画像の下に説明文が表示される形となります。

新しいDropShadowEffectのインスタンスdrEffectオブジェクトを生成します。プロパティであるOpacityに0.6、ShadowDepthに8を指定します。透過度が80%で、画像と画像の影との間の距離が8である影が表示されます。

新しいImageのインスタンスmyImageオブジェクトを生成します。Width、Heightプロパティを指定し、Marginプロパティで余白に10を指定します。Sourceプロパティには、画像を保管しているImageフォルダと要素の値を保持しているimageName変数を連結して、相対Uriで指定します。Effectプロパティに先に設定したdrEffectオブジェクトを指定します。

新しいTextBlockのインスタンスmyTextBlockオブジェクトを生成します。Widthプロパティを指定し、Textプロパティに要素の値を指定します。

myStackPanelオブジェクトにAddメソッドで画像を追加し、同じく説明を追加します。StackPanelの新しいリストとして作成しておいた、myStackArrayオブジェクトにAddメソッドで、画像と説明の追加されたmyStackPanelオブジェクトを追加します。myTabItemオブジェクトのContentプロパティにmyStackPanelオブジェクトを指定し、TabControlにAddメソッドで、myTabItemオブジェクトを指定します。TabControlの中に、タブによって切り替わる、画像とその説明文が配置されることになります。

■TabControlのタブが切り替えられた時の処理

※画像と説明文のテキストが回転する処理

新しいStoryBoardとDoubleAnimation(myStoryBoardとmyDoubleAnimation)のインスタンスを生成します。2秒かけて0°~360°まで回転させるため、DoubleAnimationのFromに0を指定し、Toには360を指定し、Durationには2秒を指定します。

新しいRotateTransformのインスタンスを生成します。RotateTransformは、指定された点を中心としてオブジェクトを時計回りに回転させるクラスです。CenterXとCenterYに、画像の中心点の座標値を指定します。

TablControlの選択されたタブのインデックス(SelectedIndex)に該当する、myStackArrayオブジェクトのRenderTransformプロパティに、myRotateTransformオブジェクトを指定します。RenderTransFormプロパティでは、UIElement の描画位置に関係する変換情報を設定することができます。myStackArrayオブジェクトにRenderTransformプロパティが設定されていない場合は、新しいRotateTransformオブジェクトのインスタンスを生成し、myStackArrayオブジェクトのRenderTransformプロパティにmyRotateTransformオブジェクトを指定します。

SetTargetメソッドでタイムラインにDoubleAnimationのインスタンスであるmyDoubleAimationを指定し、タイムラインの対象となるオブジェクトにRotateTransformのインスタンスであるmyRotateTransformを指定します。

また、SetTargetPropertyメソッドで、タイムラインにDoubleAnimationのインスタンスであるmyDoubleAimationを指定し、アニメーション化するプロパティにNew PropertyPath("(RotateTransform.Angle)")と指定し、Angleプロパティを指定して回転させます。

StoryBoardのインスタンスmyStoryBoardにAddメソッドでmyDoubleAnimationを追加します。BeginメソッドでStoryBoardを実行します。これで、画像とテキストの追加されたmyStackArrayオブジェクトが回転します。

※画像が近づいてくるアニメーション

新しいStoryBoardとDoubleAnimationのインスタンス(myStoryBoard2とmyDoubleAnimation2)を生成します。

2秒をかけて、オブジェクトをZ軸に沿って、-2000~0まで移動させるため、DoubleAnimationのFromに-2000を、Toには0を、Durationには2秒を指定します。

新しいPlaneProjectionのインスタンスを生成します。PlaneProjectionは、オブジェクトに対する遠近法変換を表わすクラスです。TablControlの選択されたタブのインデックス(SelectedIndex)に該当する、myStackArrayオブジェクトのProjectionプロパティに、myPlaneProjectionオブジェクトを指定します。Projectionプロパティは、UIElement のレンダリング時に射影を設定できるプロパティです。

myStackArrayオブジェクトにProjectionプロパティが設定されていない場合は、新しいPlaneProjectionオブジェクトのインスタンスを生成し、myStackArrayオブジェクトのProjectionプロパティにmyPlaneProjectionオブジェクトを指定します。

SetTargetメソッドで、タイムラインにDoubleAnimationのインスタンスであるmyDoubleAimation2を指定し、タイムラインの対象となるオブジェクトにPlaneProjectionのインスタンスであるmyPlaneProjectionを指定します。SetTargetPropertyメソッドで、タイムラインにDoubleAnimationのインスタンスであるmyDoubleAimation2を指定し、アニメーション化するプロパティにNew PropertyPath("(PlaneProjection.LocalOffsetZ)")と指定します。

StoryBoardのインスタンスmyStoryBoard2にAddメソッドでmyDoubleAnimation2を追加します。BeginメソッドでStoryBoardを実行します。これで、画像とテキストの追加されたmyStackArrayオブジェクトが近づくように表示されます。

四国のSOHO。薬師寺国安(VBプログラマ)と、薬師寺聖(デザイナ、エンジニア)によるコラボレーション・ユニット。1997年6月、Dynamic HTMLとDirectAnimationの普及を目的として結成。共同開発やユニット名義での執筆活動を行う。XMLおよび.NETに関する著書や連載多数。最新刊は「Silverlight実践プログラミング」両名とも、Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。http://www.PROJECTKySS.NET/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています