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

2011年1月11日(火)
PROJECT KySS

画像が削除された時、逆の動きを与えて画像が並び替わる

次に紹介するのは、ListBoxに表示されている画像の一覧から、任意の画像を選択すると、その画像が削除され、逆の動きを与える、BackEaseイージングを伴って画像が並び替わるサンプルです。

実装する機能の動作は次の通りです。

ListBox内の画像一覧から任意の画像を選択して削除すると、逆の動きを伴った動作で画像が並び替わります(図9)。

図9: 逆の動きを伴った動作で、画像が並び替わる(クリックで拡大)

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

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

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

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

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

要素のプロパティ内の[レイアウト]を展開して、Widthに800、Heightに600を指定します。次にツールボックスからTextBlockコントロール、ListBoxをレイアウトします。TextBlockコントロールの、Text、FontSize、FontWeightを指定します(図10)。

図10: TextBlockとListBoxコントロールをレイアウトした(クリックで拡大)

書き出されたXAMLコードをリスト4のように編集します。

リスト4: 編集されたXAMLコード(MainPage.xaml)

(1)<ListBox>要素のテンプレートを定義します。<UserControl.Resources>内に、
<UserControl.Resources>
        <DataTemplate x:Key="ListBoxTemplate">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
              </Grid.RowDefinitions>
            <Image x:Name="image" Width="160" Height="120" Source="{Binding 画像名}" Margin="5"/>
        </Grid> 
       </DataTemplate>

と記述し、ListBoxTemplateというキーのテンプレートを定義します。<Grid.RowDefinitions> プロパティ要素内で、<RowDefinition/>要素を定義すると、<Grid>要素に適用する1行が定義されます。<Image>要素を記述します。Sourceプロパティに{Binding 画像名}と指定します。ここで指定した「画像名」はプログラムコード内のクラスで定義するプロパティ名と同じである必要があります。Width、Height、Marginプロパティを設定します。Marginプロパティには5を指定し、画像の周囲に5ピクセルの余白を設けます。

(2)<ListBox>要素だけでは、画像は縦1列に並んで表示されてしまいます。そこで、<controlsToolkit:WrapPanel>要素を<ItemsPanelTemplate>要素内に記述します。
<ItemsPanelTemplate x:Key="WrapPanelTemplate">
            <toolkit:WrapPanel Width="753" />
  </ItemsPanelTemplate>
のように記述して、WrapPanelTemplateというキーのテンプレートを定義します。

(3)これらの定義済みListBoxTemplateとWrapPanelTemplateを、x:NameがListBox1である<ListBox>要素に、
ItemsPanel="{StaticResource WrapPanelTemplate}" ItemTemplate="{StaticResource ListBoxTemplate}"
のように指定します。StaticResourceは、定義済みのリソースを参照します。

<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_Remove.MainPage"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" Width="800" Height="600">
    <UserControl.Resources> ■(1)
        <DataTemplate x:Key="ListBoxTemplate">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
              </Grid.RowDefinitions>                      
            <Image x:Name="image" Width="160" Height="120" Source="{Binding 画像名}" Margin="5"/>
        </Grid> 
       </DataTemplate>
        <ItemsPanelTemplate x:Key="WrapPanelTemplate">■(2)
            <toolkit:WrapPanel Width="753" />
        </ItemsPanelTemplate>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White">
        <TextBlock Height="39" HorizontalAlignment="Left" Margin="24,12,0,0" x:Name="TextBlock1" Text="選択した画像が削除されます" VerticalAlignment="Top" Width="464" FontSize="24" FontWeight="Bold" />
        <ListBox Height="518" HorizontalAlignment="Left" Margin="24,57,0,0" x:Name="ListBox1" VerticalAlignment="Top" Width="753" ItemsPanel="{StaticResource WrapPanelTemplate}" ItemTemplate="{StaticResource ListBoxTemplate}"/>■(3)
    </Grid>
</UserControl>

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

次に処理を記述します。

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

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

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

Option Strict On

LINQ to XMLでXMLを処理するクラスの含まれる、System.Xml.Linq名前空間をインポートします。
Imports System.Xml.Linq

ImageInfoクラスを定義し、String型の「画像名」プロパティを定義します。
Public Class ImageInfo
    Public Property 画像名 As String
End Class

~コード略~

■ページが読み込まれた時の処理
XElement.LoadメソッドでXML文書ファイル(Photo.xml)を読み込みます。読み込んだXML文書から<画像名>要素のコレクションを取得するクエリ(query)を定義します。ImageInfoオブジェクトのリストとして作成するmyImageInfoを宣言し、クエリ(query)を実行します。クエリコレクション内を変数resultで反覆処理しながら、以下の処理を実行します。
Addメソッドで、myImageInfoクラスの各プロパティ(「画像名」)に、XMLの要素(<画像名>)の値を追加します。このプロパティの値が、XAML内のBindingの値にバインドされます。
ListBoxコントロールのItemSourceプロパティに、myImageInfoオブジェクトを指定します。
これで、ListBoxに画像の一覧が表示されます。
    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

        Dim myImageInfo As New List(Of ImageInfo)

        For Each result In query
            myImageInfo.Add(New ImageInfo With {.画像名 = "Image/" & result.Value})
        Next
        ListBox1.ItemsSource = myImageInfo
    End Sub
~コード略~

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

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

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