次に、[ソリューション・エクスプローラー]内の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の主要なメソッドについても、解説する。
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の値を渡す。
この処理が今回のアプリの肝となる。プログラム上でストーリーボード処理を行う。
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の値を、文字列”/”で連結して表示する。
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メソッドを実行する。
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.