連載
» 2013年12月16日 18時00分 公開

2カ月で160本作った還暦開発者が送る10のアプリ開発ノウハウ(10):ストーリーボードを使い画像をY軸を中心に立体的に回転させるには (2/3)

[薬師寺国安,PROJECT KySS]

書き出されるXAMLの編集

 書き出されるXAMLをリスト1のように編集する。ストーリーボードのコード部分は省略している。

※ストーリーボードのコードは省略しているが、Storyboard要素のCompletedイベントには、_StoryBoard_Completedイベントハンドラを追加してほしい。

<Page
    x:Class="ImageRotationY.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ImageRotationY"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.Resources>
〜ImageShowStoryboardのコードは省略〜
    </Page.Resources>
    <Viewbox>■(1)
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <TextBlock HorizontalAlignment="Left" Height="68" Margin="24,10,0,0" TextWrapping="Wrap" Text="画像をY軸を中心に回転" VerticalAlignment="Top" Width="538" FontFamily="Meiryo UI" FontSize="48" FontWeight="Bold"/>
            <Button x:Name="folderSelectButton" Content="フォルダーを選択" HorizontalAlignment="Left" Height="68" Margin="642,10,0,0" VerticalAlignment="Top" Width="368" FontFamily="Meiryo UI" FontSize="36"/>■(2)
            <ScrollViewer HorizontalAlignment="Left" Height="655" Margin="10,103,0,0" VerticalAlignment="Top" Width="1346">■(3)
                <GridView Height="621" Width="1310" x:Name="GridView1"/>■(3)
            </ScrollViewer>■(3)
            <Image x:Name="Image1" Width="64" Height="48" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">■(4)
                <Image.RenderTransform>
                    <CompositeTransform/>
                </Image.RenderTransform>
            </Image>■(4)
            <ProgressRing Margin="609,347,600,280" Width="157" Height="141" x:Name="ProgressRing1" IsActive="False" IsEnabled="False"/>■(5)
            <TextBlock x:Name="countTextBlock" HorizontalAlignment="Left" Height="68" Margin="1072,10,0,0" TextWrapping="Wrap"  VerticalAlignment="Top" Width="249" FontFamily="Meiryo UI" FontSize="48" TextAlignment="Center"/>■(2)
        </Grid>
    </Viewbox>■(1)
</Page>
リスト 書き出されたMainPage.xamlのコード(ストーリーボードのコードは省略)

 以上、全てをレイアウトしたのが図10だ。

図10 各コントロールを配置した結果

 以降は、ソースコードに割り振った番号ごとに詳細に見ていこう。

(1)

 Grid要素全体をViewBox要素で囲む。ViewBox要素は、伸縮およびスケーリングを実行して単一の子を使用可能な領域全体に引き伸ばすことができるコンテンツ・デコレータを定義する。

(2)

 「folderSelectButton」という名前の、フォルダーを選択するボタンとなるButton要素を配置する。

(3)

 ScrollViewer要素を配置し、その子要素として「GridView1」という名前のGridView要素を配置する。

(4)

 「Image1」という名前のImage要素を配置し、Widthに「64」、Heightに「48」、Stretchに「Uniform」と指定しておく。また、画像の回転が中心を軸に回転するように、RenderTransformOriginプロパティに「0.5,0.5」と指定しておく。

 以下のコードは、Expression Blend上で、ストーリーボードを設定した際に、自動的に追加されたコードだ。CompositeTransformは、オブジェクトに複数の異なる変換を適用する要素だ。

  <Image.RenderTransform>
      <CompositeTransform/>
  </Image.RenderTransform>

(5)

 「ProgressRing1」という名前のProgressRing要素を配置する。IsActiveとIsEnabledプロパティに「False」を指定して、最初の状態では動作不可としている。画像を読み込む間、プログレスリングが表示されるようにするものだ。

(6)

 名前が「countTextBlock」というTextBlockコントロールを配置する。選択したフォルダー内の画像の個数を表示する。

メイン画面のロジックコードを記述する(MainWindow.xaml.vb)

 次に、[ソリューション・エクスプローラー]内の「MainWindow.xaml」を展開して表示される、「MainWindow.xaml.vb」のコードを記述する。

 ここでは、コードが長くなるため一部コードを省略する。全てのコードを見る場合は、サンプルをダウンロードして「MainWindow.xaml.vb」ファイルを見ていただきたい。

‘ UIの作成と管理を行うクラスを提供します。これにより、ユーザーは、ファイルの閲覧、開くファイルの選択、名前、拡張子、
‘ ファイルの格納場所の選択を行うことのできるクラスを提供する、Windows.Storage.Pickers名前空間をインポートする。
Imports Windows.Storage.Pickers
‘ ファイル、フォルダーおよびアプリケーションの設定を管理するクラスの含まれる、
‘ Windows.Storage名前空間をインポートする。
Imports Windows.Storage
‘ コンテキストメニューおよびメッセージダイアログのサポートを提供するクラスの含まれる、
‘ Windows.UI.Popups名前空間をインポートする。
Imports Windows.UI.Popups
‘ アニメーションおよびストーリーボードAPIを提供するクラスの含まれる、
‘ Windows.UI.Xaml.Media.Animation名前空間をインポートする。
Imports Windows.UI.Xaml.Media.Animation
Public NotInheritable Class MainPage
    Inherits Page
‘ フォルダーとその内容を操作し、その情報を提供するクラスである、StorageFolder型のメンバー変数myFolderを宣言する。
    Private myFolder As StorageFolder
‘ 要素の厳密に型指定された(この場合IStorageFile)読み取り専用のコレクションを表す、
‘ IReadOnlyCollection(Of IStorageFile)型のメンバー変数myImageCollectionsメンバー変数を宣言する。
    Private myImageCollections As IReadOnlyCollection(Of IStorageFile)
‘ SourceプロパティおよびImageSourceプロパティの実際的なオブジェクトソース型を提供するクラスである、
‘ BitmapImage型のメンバー変数myBmpを宣言する。
    Private myBmp As BitmapImage
‘ Imageクラス型のメンバー変数myImageを宣言する。
    Private myImage As Image
‘ タイムラインを使用してアニメ―ションを制御し、子アニメーションのオブジェクトやプロパティのターゲット情報を提供する
‘ クラスである、Storyboard型メンバー変数_StoryBoardを宣言する。
    Private _StoryBoard As Storyboard

「フォルダーを選択」ボタンがタップされたときの処理(folderSelectButton_Clickメソッド処理)

    Private Async Sub folderSelectButton_Click(sender As Object, e As RoutedEventArgs) Handles folderSelectButton.Click
        GridView1.Items.Clear()
        Try
            ProgressRing1.IsActive = True
            ProgressRing1.IsEnabled = True
            Dim myFolderPicker = New FolderPicker
            myFolderPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary
            myFolderPicker.FileTypeFilter.Add(".jpg")
            myFolderPicker.FileTypeFilter.Add(".png")
            myFolder = Await myFolderPicker.PickSingleFolderAsync
            myImageCollections = Await myFolder.GetFilesAsync
            countTextBlock.Text = "[" & myImageCollections.Count & "]"
            If myFolderPicker Is Nothing = False Then
                Await DataShow()
            Else
                ProgressRing1.IsActive = False
                ProgressRing1.IsEnabled = False
                Exit Sub
            End If
        Catch
            ProgressRing1.IsActive = False
            ProgressRing1.IsEnabled = False
            countTextBlock.Text = String.Empty
            Exit Sub
        End Try
    End Sub

 以降、上記コードの中身を詳細に見ていこう。

 まず、非同期処理で行われるためメソッドの先頭にAsyncを追加している。

 次に、ProgressRing1を表示し、新しいFolderPickerのインスタンスmyFolderPickerオブジェクトを作成する。FolderPickerクラスは、ユーザーがフォルダーを開いて選択できるようにするUIを提供するクラスだ。

 フォルダーピッカーがユーザーに示すフォルダーを検索する際の初期位置を設定する、SuggestedStartLocationプロパティにピクチャライブラリを指定しておく。

 フォルダーピッカーが表示するファイルの種類のコレクションを取得するFileTypeFilter.Addメソッドで、「.jpg」と「.png」ファイルを追加する。これで、表示できるファイルはjpgとpngファイルだけということになる。

 PickSingleFolderAsyncで、ユーザーがフォルダーを選択できるようにするfolderPickerオブジェクトを表示し、メンバー変数「myFolder」で参照する。

 指定したフォルダー内のファイルをGetFilesAsyncメソッドで取得し、メンバーコレクション変数myImageCollectionsで参照する。

 countTextBlock内にCountプロパティで、myImageCollections内のファイルの個数を取得して、表示する。

 次は、フォルダーが選択されたときの処理だ。選択したフォルダー内の画像を表示して、マウスの移動で、画像を、Y軸を中心に回転させたり、ImageShowStoryboardを実行するDataShowタスクを実行する。

 次はフォルダーを選択時点でキャンセルした場合の処理だ。ProgressRing1の動作を停止する。例外処理が発生した場合も、これと同じ処理を行う。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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