ブラウザ上で複数の画像を自動的に並び替える

2011年1月11日(火)
PROJECT KySS

今日から5回に亘って、ビヘイビアを用いた、動きのあるページのサンプルを作っていきます。解説の手順に従って、皆さんにも、ぜひ作成実行をしていただきたいと思います。

では、ビヘイビアの1つである、FluidMoveBehaviorビヘイビアを使って、動きのあるページを作ってみましょう。FluidMoveBehaviorビヘイビアは、要素の位置の変化をアニメーション化するものです。Visual Studio 2010(以下VS2010)とExpression Blend 4(以下Blend4)を用いて、FluidMoveBehaviorを使ったサンプルを作成します。

初回は、ブラウザのサイズ変更に伴って自動的に画像が並び替わるサンプルと、選択された画像が削除された時、FluidMoveBehaviorビヘイビアの機能が働く、2つのサンプルを紹介します。最初は「ブラウザの画面のサイズ変更に伴って、自動的に複数の画像が並び替わる」サンプルの紹介です。

では、まず初めに、このプログラムで実装する機能の動作を、下記に解説しておきます。ブラウザに表示された、複数の画像が、ブラウザの画面のサイズ変更に伴って、自動的に並び替わります(図1)。

図1: ブラウザの画面のサイズ変更によって画像が自動的に並び替わっている (クリックで拡大)

今回のサンプルは以下よりダウンロードできます。
→ SL4_FluidMoveBehavior_WrapPanel.zip
→ SL4_FluidMoveBehavior_Remove.zip

新規プロジェクトの作成

早速サンプルを作っていきましょう。

VS 2010のメニューから「ファイル(F)/新規作成(N)/プロジェクト(P)」を選択します。本稿では開発言語にVisual Basicを用います。次に、「Silverlight アプリケーション」を選択して、「名前(N)」に任意のプロジェクト名を指定します。ここでは「SL4_FluidMoveBehavior_WrapPanel」という名前を付けています。

.NET Frameworkのバージョンはデフォルトの「4」、「新しいSilverlightアプリケーション」の[オプション]の「Silverlightのバージョン(L)」も、デフォルトの「Silverlight 4 」を選択します。

デフォルト設定で新規プロジェクトを作成すると、「プロジェクト名.Web」というフォルダが自動的に作成されます。このフォルダが作成された状態で、xaml.vbファイルやxamlファイルを編集して処理を記述後、「デバッグ(D)/デバッグ開始(S)」を実行すると、コードの変更が反映されなかったり、エラーが表示される場合があります。これは、SL4_FluidMoveBehavior_WrapPanelプロジェクトとSL4_FluidMoveBehavior_WrapPanel.Webの依存関係が設定されていないからです。そこで、この段階で、依存関係の設定を行っておきます。

ソリューションエクスプローラー内のソリューションプロジェクト名を選択して、マウスの右クリックで表示されるショートカットメニューから、「プロジェクト依存関係(S)」を選択します。「プロジェクトの依存関係」ダイアログボックスの「依存先(D)」内のチェックボックスにチェックを付けます(図2)。

図2: 依存関係を設定する

VS 2010のデザイン画面上で、コントロールのレイアウトとBlend4での設定

VS2010上のツールボックスからWrapPanelコントロールを1個デザイン画面上にドラッグ&ドロップします(図3)。要素のWidthとHeightは設定せず、デフォルトの状態(Auto)にしておいてください。

図3: WrapPanelコントロールをレイアウトする

このWrapPanelコントロールに追加する画像をソリューションエクスプローラー内に取り込んでおきます。ソリューションエクスプローラー内の「SL4_FluidMoveBehavior_WrapPanel」を選択し、マウスの右クリックで表示されるメニューから、「追加(D)/新しいフォルダー(D)」を選択し、新規フォルダを作成します。フォルダ名はデフォルトのNewFolder1ではなくImageに変更しておきましょう。

作成したフォルダ上を右クリックして表示されるメニューから「追加(D)/既存の項目(G)」を選択して、WrapPanelコントロールに表示する画像を追加します。

次にXMLファイルを追加しておきます。ソリューションエクスプローラーから「SL4_FluidMoveBehavior_WrapPanel」を選択し、マウスの右クリックで表示されるメニューから、「追加(D)/既存の項目(G)」と選択して、XML文書ファイル(リスト1)を追加します。また、XMLデータはLINQ to XMLで処理するため、「プロジェクト(P)/参照の追加(F)」からSystem.Xml.Linqを追加しておきます。

このあたりの操作手順については、既に掲載済みの「いまからはじめるSilverlight 4」の連載を参考にしてください。

ダウンロード・ファイルには、XML文書ファイル、画像ファイルとも追加済みです。

リスト1: 画像ファイル名を記録したXML文書ファイル(Photo.xml)

<?xml version="1.0"?>
<画像>
	<情報>
		<画像名>おしろい花.jpg</画像名>
		<画像名>サルビア.jpg</画像名>
		<画像名>ベゴニア.jpg</画像名>
		~<画像名></画像名>繰り返し~
	</情報>
</画像>

次に、ソリューションエクスプローラー内の、MainPage.xamlを選択し、マウスの右クリックで表示されるメニューの、「Expression Blendを開く(X)」を選択し、Blend4を起動します。

アートボードが表示されます。「オブジェクトとタイムライン(B)」内のWrapPanel1選択すると、アートボード上でWrapPanelが選択状態になります。WrapPanelコントロール上でマウスの右クリックをし、表示されるメニューから、「自動サイズ設定/ページ幅に合わせる」と選択します。するとWrapPanelコントロールがUserControlのサイズと同じになります(図4)。

図4: WrapPanelコントロールのサイズがUserControlと同じに設定される(クリックで拡大)

FluidMoveBehaviorを設定する

「アセット」パネルから「ビヘイビア」を選択し、FluidMoveBehaviorを、「オブジェクトとタイムライン(B)」内のWrapPanel1上にドラッグ&ドロップします(図5)。

図5: FluidMoveBehaviorをWrapPanel1上にドラッグドロップする

WrapPanel1要素の子としてFluidMoveBehaviorが追加されます(図6)。

図6: WrapPanel1要素の子としてFluidMoveBehaviorが追加された

FluidMoveBehaviorのプロパティを設定します。[共通プロパティ]内のAppliesToプロパティにChildrenを選択します。AppliesToプロパティにはビヘイビアを適用するオブジェクトを選択します。Childrenでは指定したオブジェクトのすべての子に、ビヘイビアが適用されます。デフォルトはSelfですが、これは、ビヘイビアがアタッチされているオブジェクトに適用されます。EaseXとEaseYをドロップダウンリストから選択します(図7)。

図7: EaseXの値を一覧から選択している

EaseXプロパティには水平方向のイージング機能を指定します。ここではCubicInOutを指定しています。

EaseYプロパティには垂直方向のイージング機能を指定します。ここではCubicInOutを指定しています。

[タグプロパティ]内のInitialTagとTagプロパティはデフォルトの「Element」のままにしておきます(図8)。

InitialTagプロパティには、この要素の派生元のように見せるタグを指定します。スタンドアロンでは「Element」を選択し、データバインドされている時は「DataContext」を選択します。

Tagプロパティには、データストアの読み取りと書き込みの対象となるデータの種類を指定します。スタンドアロンでは「Element」、データバインドされている時は「DataContext」を指定します。

今回はデータバインドを使用しませんので、デフォルトの「Element」のままにしておきます。

図8: InitialTagとTagプロパティはデフォルトの「Element」のままにしておく

以上でBlend4の操作を終わり、VS2010に戻ります。

筆者の環境だけかどうかわかりませんが、VS2010の画面に戻ると、FluidMoveBehaviorビヘイビア関連のXAMLコードに波線が表示され、エラーとなってデザイン画面が表示されない場面がありました。この場合は一度VS2010を終了し、再度起動し直すことで解決しました。

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

書き出されるXAMLコードはリスト2のようになります。

リスト2: 書き出されたXAMLコード(MainPage.xaml)

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" x:Class="SL4_FluidMoveBehavior_WrapPanel.MainPage"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
(1)<toolkit:WrapPanel>要素内の、<i:Interaction.Behaviors>プロパティ要素内に、<ei:FluidMoveBehavior>要素が記述されています。<CubicEase>要素のEasingModeプロパティにEaseInOutが指定されています。Blend4では、EaseXとEaseYにCubicInOutを選択していましたので、XAMLに書き出される場合は、<CubicEase EasingMode="EaseInOut"/>となります。
        <toolkit:WrapPanel x:Name="WrapPanel1" >■(1)
        	<i:Interaction.Behaviors>
        		<ei:FluidMoveBehavior AppliesTo="Children">
        			<ei:FluidMoveBehavior.EaseY>
        				<CubicEase EasingMode="EaseInOut"/>
        			</ei:FluidMoveBehavior.EaseY>
        			<ei:FluidMoveBehavior.EaseX>
        				<CubicEase EasingMode="EaseInOut"/>
        			</ei:FluidMoveBehavior.EaseX>
        		</ei:FluidMoveBehavior>
        	</i:Interaction.Behaviors>
        </toolkit:WrapPanel>
    </Grid>
</UserControl>

次に処理を記述します。

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

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

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

Option Strict On

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

Partial Public Class MainPage
    Inherits UserControl

    Public Sub New()
        InitializeComponent()
    End Sub

■ページが読み込まれた時の処理
XElement.LoadメソッドでXML文書ファイル(Photo.xml)を読み込みます。読み込んだXML文書から<画像名>要素のコレクションを取得するクエリ(query)を定義します。queryを実行します。クエリコレクション内を変数resultで反復処理しながら以下の処理を実行します。
新しいImageのインスタンスmyImageオブジェクトを生成します。Width、Height、Margin、Sourceプロパティを指定します。Marginプロパティに10を指定することで画像の周囲に10ピクセルの余白が生まれます。Sourceプロパティに指定する画像には、UriKind.Relativeを指定して、相対Uriとします。
各プロパティの設定されたmyImageオブジェクトをWrapPanelコントロールに追加します。

    Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        Dim xmldoc As XElement = XElement.Load("Photo.xml")
        Dim query = From c In xmldoc.Descendants("画像名") Select c
        For Each result In query
            Dim myImage As New Image
            With myImage
                .Width = 160
                .Height = 120
                .Margin = New Thickness(10)
                .Source = New BitmapImage(New Uri("Image/" & result.Value, UriKind.Relative))
            End With
            WrapPanel1.Children.Add(myImage)
        Next
    End Sub
End Class

VS2010のメニューから、「デバッグ(D)/デバッグ開始(S)」と選択して動作を確認しておきましょう。

四国の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メルマガ会員のサービス内容を見る

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