指定したフォルダー内の画像をスライド形式で表示させるには:2カ月で160本作った還暦開発者が送る10のアプリ開発ノウハウ(5)(2/2 ページ)
古(いにしえ)からのVBでWindows 8.1向けのさまざまな機能のアプリを開発する手順やコツを解説していく。今回は、指定したフォルダー内の画像を順次スライドさせながら表示させる方法をサンプルを交えて解説する。
ロジックコードを記述する(MainWindow.xaml.vb)
次に、[ソリューション・エクスプローラー]内のMainWindow.xamlを展開して表示される「MainWindow.xaml.vb」のコードを記述する。
ここでは、コードが長くなるため、コードを一部省略している。全てのコードはサンプルをダウンロードして「MainWindow.xaml.vb」ファイルで確認してほしい。
Option Strict On
‘ ファイルの閲覧、開くファイルの選択、名前、拡張子、ファイルの格納場所の選択を行うことのできるクラスの含まれる、
’ Windows.Storage.Pickers名前空間をインポートする。
Imports Windows.Storage.Pickers
‘ ファイル、フォルダーおよびアプリケーションの設定を管理するクラスの含まれる、
‘ Windows.Storage名前空間をインポートする。
Imports Windows.Storage
‘ コンテキストメニューおよびメッセージダイアログのサポートを提供するクラスの含まれる、
‘ Windows.UI.Popups名前空間をインポートする。
Imports Windows.UI.Popups
‘ 遷移アニメーション、表示状態、またはアニメーションUIのコンポーネントに、アニメーションおよび
‘ ストーリーボードAPIを提供するクラスの含まれる、Windows.UI.Xaml.Media.Animation名前空間をインポートする。
Imports Windows.UI.Xaml.Media.Animation
Public NotInheritable Class MainPage
    Inherits Page
‘ BitmapSource型のリストであるメンバー変数imageFileを宣言する。
    Private imageFile As List(Of BitmapSource)
    Private index As Integer = 0
    Private myCount As Integer = 0
‘ フォルダーとその内容を操作し、その状況を提供するStorageFolderクラス型のメンバー変数myFolderを宣言する。
    Private myFolder As StorageFolder
‘ 要素の厳密に型指定(この場合IStorage型)された、読み取り専用のコレクションを表す、
‘ IReadOnlyCollection(Of IStorageFile)型のメンバー変数myFileCollectionsを宣言する。
    Private myFileCollections As IReadOnlyCollection(Of IStorageFile)
以降、MainWindow.xaml.vbの主要なメソッドについても、解説する。
[フォルダーを選択]ボタンがタップされた時の処理(folderSelectButton_Clickメソッド処理)
    Private Async Sub folderSelectButton_Click(sender As Object, e As RoutedEventArgs) Handles folderSelectButton.Click
        index = 0
        Try
            Dim myFolderPicker = New FolderPicker
            myFolderPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary
            myFolderPicker.FileTypeFilter.Add(".jpg")
            myFolderPicker.FileTypeFilter.Add(".png")
            myFolder = Await myFolderPicker.PickSingleFolderAsync
            myFileCollections = Await myFolder.GetFilesAsync
            myCount = myFileCollections.Count
            imageFile = New List(Of BitmapSource)
            For Each result In myFileCollections
                Dim myBmp As New BitmapImage
                myBmp.SetSource(Await result.OpenReadAsync)
                imageFile.Add(myBmp)
            Next
            countTextBlock.Text = index + 1 & "/" & myCount
            ImageSlide(index)
        Catch
            Exit Sub
        End Try
    End Sub
以降、上記コードの中身を詳細に見ていこう。
まず、非同期処理が行われるため、メソッドの先頭にAsyncを追加する。
次にユーザーがフォルダーを開いて選択できるようにするUI要素を表す、新しいFolderPickerのインスタンス、myFolderPickerオブジェクトを作成する。
フォルダー・ピッカーがユーザーに示すフォルダーを検索する際の初期位置を設定する、SuggestedStartLocationプロパティに、PicturesLibraryを指定する。フォルダー・ピッカーが表示するファイルの種類を指定するFileTypeFilterで、「.jpg」と「.png」を指定しておく。
指定方法は、jpgを例にとると、「myFolderPicker.FileTypeFilter.Add(".jpg")」というコードにし、「("*.jpg")」ではないことに注意してほしい。
PickSingleFolderAsyncメソッドで、ユーザーがフォルダーを選択できるようにfolderPickerオブジェクトを表示する。
GetFilesAsyncメソッドでフォルダー内のファイルを取得し、メンバー変数myFileCollectionsで参照しておく。
Countプロパティでフォルダー内のファイルの個数を取得し、メンバー変数myCountに格納しておく。
BitmapSource型のリストである、新しいインスタンス、imageFileオブジェクトを作成する。
コレクション・メンバー変数myFileCollections内のファイルを、変数resultに格納しながら、以下の処理を行う。
新しいBitmapImageのインスタンス、myBmpオブジェクトを作成する。SetSourceメソッドに、「Await result.OpenReadAsync」と指定して、ランダムアクセス用のストリームを開き、myBmpオブジェクトに、BitmapSourceのソースイメージを設定する。
BitmapSource型の新しいリストであるimageFileオブジェクトに、AddメソッドでmyBmpオブジェクトを追加する。
「何枚目中何枚目の画像か」を表示するcountTextBlockに、1ずつ加算されるメンバー変数indexとmyCountの値を、文字列「/」で連結して表示する。
画像をスライド表示するImageSlideメソッドを実行する。引数として、1ずつ加算されるメンバー変数indexの値を渡す。
画像をスライドして表示させるImageSlideメソッド処理
この処理が今回のアプリの肝となる。プログラム上でストーリーボード処理を行う。
    Private Sub ImageSlide(ByVal Index As Integer)
        If Image2.Source Is Nothing Then
            Image2.Source = imageFile(0)
        Else
            Image1.Source = imageFile(myCount - 1)
            Dim myTranslateTransForm As TranslateTransform = DirectCast(Image2.RenderTransform, TranslateTransform)
            Image2.Source = imageFile(Index)
       ‘ これより以下の処理が今回の肝。ストーリーボード処理をプログラム上で実行する。
            Dim myDoubleAnimation As New DoubleAnimation
            With myDoubleAnimation
                .From = 600
                .To = 0
                .Duration = New Duration(TimeSpan.FromSeconds(2))
                .EasingFunction = New BackEase()
            End With
            Dim myStoryBoard As New Storyboard
            Storyboard.SetTarget(myDoubleAnimation, myTranslateTransForm)
            Storyboard.SetTargetProperty(myDoubleAnimation, "TranslateTransform.X")
            myStoryBoard.Children.Add(myDoubleAnimation)
            myStoryBoard.Begin()
            If Index <= 0 Then
                Index = 0
                prevButton.IsEnabled = False
            End If
            If Index >= myCount - 1 Then
                nextButton.IsEnabled = False
                Index = myCount - 1
            End If
            countTextBlock.Text = Index + 1 & "/" & myCount
            End If
    End Sub
Image2コントロール(前面に表示される画像)のSourceプロパティに画像が指定されていない場合は、BitmapSource型のリストであるメンバー変数imageFileのインデックスが「0」の画像を指定する。そうでない場合は、以下の処理を行う。
Image1コントロール(背面に表示される画像)のSourceプロパティにおいて、BitmapSource型のリストであるメンバー変数imageFileのインデックスに、myCountから-1した値の画像を指定する。背面には、指定したフォルダー内の、最後の画像が表示されることになる。
Image2オブジェクトのTranslateTransformオブジェクトを取得する。TranslateTransformクラスは、2次元X、Y座標系内のオブジェクトを移動するクラスだ。
新しいDoubleAnimationのインスタンス、myDoubleAnimationオブジェクトを作成する。Fromには「600」、Toには「0」、Durationには「2秒」を指定する。EasingFunctionプロパティでは、アニメーションに適用されるイージング関数を設定できる。ここでは「BackEase」を指定している。BackEaseクラスは、指定されたパスのアニメーションを開始する直前に、逆の動きを与えるイージング関数を表す。
新しいStoryboardのインスタンス、myStoryBoardオブジェクトを作成する。SetTargetメソッドでタイムラインにDoubleAnimationのインスタンスであるmyDoubleAnimationオブジェクトを指定して、タイムラインの対象になるオブジェクトに、TranslateTransformとして宣言したmyTranslateTransformオブジェクトを指定する。
SetTragetPropertyメソッドで、タイムラインにDoubleAnimationのインスタンスである、myDoubleAnimationオブジェクトを指定して、アニメーション化するプロパティに、"TranslateTransform.X"と指定する。X軸に沿ってオブジェクトが水平移動する。
Storyboardのインスタンス、myStoryBoardオブジェクトにAddメソッドで、myDoubleAnimationオブジェクトを追加する。
BeginメソッドでStoryboardを実行する。
引数として渡されたIndexの値が、0か0より小さい場合は、「←(前)」アイコンの使用を不可とする。
引数として渡されたIndexの値が、指定したフォルダー内のファイルの個数を格納しているmyCount-1と同じか大きい場合は、「→(次)」アイコンの使用を不可とする。
何枚目中何枚目の画像かを表示する、countTextBoxに1ずつ加算されるメンバー変数indexと、myCountの値を、文字列”/”で連結して表示する。
「←(前)」アイコンがタップされた時の処理(prevButton_Clickメソッド処理)
    Private Sub prevButton_Click(sender As Object, e As RoutedEventArgs) Handles prevButton.Click
        nextButton.IsEnabled = True
        If index <= 0 Then
            index = 0
            prevButton.IsEnabled = False
            Exit Sub
        Else
            index = index - 1
            ImageSlide(index)
        End If
    End Sub
「→(次)」アイコンの使用を可能にする。メンバー変数indexが0か0より小さい場合は、「←(前)」アイコンの使用を不可とし、処理を抜ける。そうでない場合は、メンバー変数indexを1ずつ減算し、そのindexの値を引数にImageSlideメソッドを実行する。
「→(次)」アイコンがタップされた時の処理(nextButton_Clickメソッド処理)
    Private Sub nextButton_Click(sender As Object, e As RoutedEventArgs) Handles nextButton.Click
        prevButton.IsEnabled = True
        If index >= myCount - 1 Then
            nextButton.IsEnabled = False
            index = myCount - 1
            Exit Sub
        Else
            index = index + 1
            ImageSlide(index)
        End If
    End Sub
「←(前)」アイコンの使用を可能にする。メンバー変数indexが指定したフォルダー内のファイルの個数を格納している「myCount-1」と同じか大きい場合は、「→(次)」アイコンの使用を不可とする。そうでない場合は、メンバー変数indexの値を1ずつ加算し、このindexの値を引数にImageSlideメソッドを実行する。
次回は、カメラの画像に、何か音声のコメントを付けて保存し、再生させる
今回はここまでだ。また次回の記事でお会いしよう。次回は、カメラからの画像に、何か音声のコメントを付けて保存し、再生させる
関連リンク
本コンテストでは、2013年9月1日〜12月1日に新たにWindowsストアに新規公開されたアプリを募集します。入賞したアプリの製作者には、総額130万円の賞金が授与されますので、ふるってご応募ください。
著者プロフィール
PROJECT KySS 薬師寺 国安(やくしじ くにやす)
1950年生まれ。フリーVBプログラマ。高級婦人服メーカーの事務職に在職中、趣味でVBやActiveXに取り組み、記事を執筆。2003年よりフリー。.NETやRIAに関する執筆多数。Windowsストアアプリも多数公開中(約270本)。
Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。
Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。
Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。
PROJECT KySSは、1997年に薬師寺聖と結成したコラボレーション・ユニット
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
今でしょ! の終わりに安齋、家入らが評価したアプリとは〜「エイっと作ろう! Windowsストア アプリ選手権」授賞式レポート
謎のキャラ今出しょう子をマスコットに据えたコンテストを勝ち上がった10作品のプレゼン模様などをお届け。
初のアジャイル/リモート開発体制でも成功できた秘訣とは〜「Windowsタブレット向けアプリ開発」先駆けインタビュー
日本料理のレシピを海外に紹介するアプリ「Ippin」。初物づくしのアプリ開発を成功させた秘訣をディレクターに聞いた。コミュニケーションツールやドキュメントに盛り込んだ数々の工夫とは、どんなものだったのだろうか。
PC制御UIの最先端Leapアプリ開発入門(3):ProcessingやWindows 8.1アプリでLeapの空間ジェスチャを使うには
画面タッチやマウスなどのように“触れる”ことなく空中ジェスチャでPC操作が可能な新しいデバイスLeap Motionを使い、これまでにないアプリを開発しましょう。今回は、ゲームループやLeapのジェスチャ3種Circle、Swipe、Tap、ProcessingのLeapジェスチャアプリ、そしてMVVMパターンで指の数を検出するC#アプリについて解説します。
Web開発者が手っ取り早くストアデビューする方法(1):Windowsストアにアプリを登録するための事前準備
Windowsストア初心者のために(主に、HTMLやJavaScriptを扱うWeb開発者向けに)、簡単なアプリを開発してWindowsストアに手っ取り早くデビューする手順を解説します。初回は、Microsoftアカウントの取得、Windowsストアアプリ開発者登録、開発環境準備について。
連載:Windowsストア・アプリ開発入門:第1回 Windowsストア・アプリってどんなもの?
ついにWindows 8.1の正式版がMSDNサブスクライバー向けに公開された。無償アップデートとなるため、今後は新しいWindows 8.1ストア・アプリが一般化するだろう。最新環境向けに新たにアプリ開発を始める人のための連載スタート。
特集:次期Windows 8.1&Visual Studio 2013 Preview概説(前編):大きく変わるWindowsストア・アプリ開発 〜 ビュー状態に関連する変更点
Windows 8.1(Preview版)の変更点や新機能を開発者視点で紹介。Windows 8用に作られたWindowsストア・アプリにはどんな影響があるのか?
UXClip(11):これからが本番、Windows 8アプリ開発
12月3日夜、Windows 8のハードウェアやアプリを開発者向けに紹介するイベントが行なわれた
Windows 8提供開始、対応アプリ登場は期待できるか?
マイクロソフトはWindows 8の提供を正式に開始した。Windowsストアもスタートし、いよいよWindows 8プラットフォームが市場投入となる。
