Saveアイコンがタップされた時の処理
変数claudiaWidthに、クラウディアの幅にX軸の拡大縮小の値myTrans.ScaleXを乗算して指定します。
変数claudiaHeightに、クラウディアの高さにY軸の拡大縮小の値myTrans.ScaleYを乗算して指定します。
ピクチャライブラリにアクセスします。
CreateFolderAsyncメソッドで、ピクチャライブラリ内にClaudiaData2というサブフォルダを作成します。CreationCollisionOption.OpenIfExistsを指定すると、既に同名フォルダが存在する場合はフォルダ名を返し、ない場合は新規に作成します。
Visual Basic の埋め込み式を用いて、ルート要素、その子要素としてを作成し、の子要素として
要素を作成します。
属性”Width”にclaudiaWidth変数の値を指定します。
属性”Height”にclaudiaHeightの値を指定します。
属性”Top”にはmyTrans.TranslateY.ToStringの値を、属性”Left”にはmyTrans.TranslateX.ToStringの値を指定します。
属性”Wav”にはメンバ変数SoundFileの値を指定します。
要素自体にはメンバ変数claudiaImageFileNameの値を指定します。
次に要素を作成し、Width属性に640、Height属性に480と指定します。
To属性には167、Left属性には303と指定しています。
要素自体の値には変数myFileNameの値を指定します。
埋め込み式の構文であるを用いています。
これは ASP.NET で使用される構文と同じです。作成したXML文書を変数saveXmlに格納します。
XElemet.Parseメソッドで、作成したXMLを文字列として読み込みます。読み込んだ結果XMLを変数resultに格納しておきます。
CreateFileAsyncメソッドで、ピクチャライブラリのClaudiaData2サブフォルダ内に現在の年月日時分秒.xmlというファイルを作成します。
CreationCollisionOption.ReplaceExistingと指定し、既に同名のファイルがある場合は上書きします。
OpenAsyncメソッドで、作成した現在の年月日時分秒.xmlを「読み取り/書き込み」モードで開き、入出力データへの、ランダムアクセスをサポートするIRandomAccessStreamインターフェース型のmyStreamで参照します。
データを出力ストリームに書き込む、新しいDataWriterのインスタンスをmyStreamで初期化し、writerオブジェクトを作成します。
出力ストリームのUnicode文字エンコードを設定する、UnicodeEncodingプロパティにUtf8を指定します。
Writeメソッドで出力ストリームにresult変数の値を書き込みます。
StoreAsyncメソッドでバッキングストアにバッファーのデータをコミットします。Canvas内をクリアします。
文字列型の新しいリストであるmyFileListオブジェクトを作成します。
GetFilesAsyncメソッドでClaudiaData2フォルダ内のファイルを取得し、コレクション変数myImageFileに格納します。
myImageFileに格納されたファイルの個数が0より大きい場合は以下の処理を行います。
コレクション変数myImageFile内を変数fileResultで反復処理しながら、fileResult.Pathで取得した絶対パス付きファイル名から、パスと拡張子を除いたファイル名を取得し、再度”.xml”という拡張子を追加して、そのファイル名をmyFileListオブジェクトに追加します。
fileListBoxのItemsSourceプロパティにmyFileListオブジェクトを指定します。これで、リストボックスにClaudiaData2内のXMLファイルが一覧表示されます。
言葉の表示されているリストボックスの使用を不可とし、Saveアイコンの使用を不可とします。
非同期処理で行われるため、メソッドの先頭にAsyncを追加します
01 | Private Async Sub saveButton_Click(sender As Object, e As RoutedEventArgs) Handles saveButton.Click |
02 | Dim claudiaWidth = CInt(myClaudiaImage.Width * myTrans.ScaleX) |
03 | Dim claudiaHeight = CInt(myClaudiaImage.Height * myTrans.ScaleY) |
04 | Dim myFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary |
05 | Dim SubFolder = Await myFolder.CreateFolderAsync("ClaudiaData2", CreationCollisionOption.OpenIfExists) |
06 | Dim saveXml As XElement = <Claudia><Info><Image Width=<%= claudiaWidth %> Height=<%= claudiaHeight %> Top=<%= myTrans.TranslateY.ToString %> Left=<%= myTrans.TranslateX.ToString %> Wav=<%= SoundFile %>><%= claudiaImageFileName %></Image><PersonalImage Width=<%= 640 %> Height=<%= 480 %> Top=<%= 167 %> Left=<%= 303 %>><%= myFileName %></PersonalImage></Info></Claudia> |
07 | Dim saveXmldoc As XElement = XElement.Parse(saveXml.ToString) |
08 | Dim result As String = saveXmldoc.ToString |
10 | Dim myXmlFile As StorageFile = Await SubFolder.CreateFileAsync(DateTime.Now.ToString("yyyy年MM月dd日HH時mm分ss秒") & ".xml", CreationCollisionOption.ReplaceExisting) |
12 | Using myStream As IRandomAccessStream = Await myXmlFile.OpenAsync(FileAccessMode.ReadWrite) |
13 | Dim writer As DataWriter = New DataWriter(myStream) |
14 | writer.UnicodeEncoding = UnicodeEncoding.Utf8 |
15 | writer.WriteString(result) |
16 | Await writer.StoreAsync |
18 | Canvas1.Children.Clear() |
20 | Dim myFileList As New List(Of String) |
21 | Dim myImageFile = Await SubFolder.GetFilesAsync |
22 | If myImageFile.Count > 0 Then |
23 | For Each fileResult As StorageFile In myImageFile |
24 | myFileList.Add(Path.GetFileNameWithoutExtension(fileResult.Path) & ".xml") |
27 | fileListBox.Items.Clear() |
29 | fileListBox.ItemsSource = myFileList |
30 | soundListBox.IsEnabled = False |
31 | saveButton.IsEnabled = False |
戻る(←)アイコンがタップされた時の処理
Frameを非表示にし、ピクチャライブラリのClaudiaData2フォルダ内にファイルが存在した場合は、リストボックスにファイルの一覧を表示し、クラウディアの画像と、音声用のファイルを表示する処理である、DataShowプロシージャを実行します。
1 | Private Sub backButton_Click(sender As Object, e As RoutedEventArgs) Handles backButton.Click |
2 | myFrame.Visibility = Windows.UI.Xaml.Visibility.Collapsed |
ファイルの一覧から任意のファイルが選択された時の処理
Frameを表示状態にし、fileListBoxから選択されたファイル名を変数mySelectedFileに格納します。
この変数を引数にDataShowPageに遷移します。
01 | Private Sub fileListBox_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles fileListBox.SelectionChanged |
02 | If fileListBox.SelectedIndex >= 0 Then |
03 | myFrame.Visibility = Windows.UI.Xaml.Visibility.Visible |
04 | mySelectedFile = fileListBox.SelectedItem.ToString |
05 | myFrame.Navigate(GetType(DataShowPage), mySelectedFile) |
次に、ソリューションエクスプローラー内のDataShowPage.xamlを展開して表示される、DataShowPage.xaml.vbをダブルクリックしてリスト5のコードを記述します。
ロジックコードを記述する
リスト5 (DataShowPage.xaml.vb)
ファイルやフォルダおよびアプリケーションの設定を管理するクラスの含まれる、Windows.Storage名前空間をインポートします。
シーケンシャルアクセスストリームおよびランダムアクセスストリームに対する読み込みと書き込みのサポートを提供するクラスの含まれる、Windows.Storage.Streams名前空間をインポートします。
1 | Imports Windows.Storage.Streams |
コンテキストメニューおよびメッセージダイアログのサポートを提供するクラスの含まれる、Windows.UI.Popups名前空間をインポートします。
1 | Imports Windows.UI.Popups |
メンバ変数mySelectedFileを宣言しておきます。
1 | Dim mySelectedFile As String |
ページがアクティブになった時の処理
音声を再生するPlayボタンの使用を可能にします。
MainPage.xamlから渡された値はe.Parameterで受け取れます。これはObject型であるためDirectCastで文字列にキャストして、メンバ変数mySelectedFileに格納します。XMLファイルが格納されています。
ピクチャライブラリにアクセスします。
CreateFolderAsyncメソッドでピクチャライブラリ内にClaudiaData2というサブフォルダを作成します。
CreationCollisionOption.OpenIfExistsと指定すると、同名フォルダがある場合は、そのフォルダ名を返し、ない場合は新規に作成します。
GetFileAsyncメソッドで、指定されたファイルの名前を使用して、現在のフォルダから1つのファイルを取得します。
取得したファイルを変数myFileで参照します。
OpenFileAsyncメソッドでmyFileを「読み込み専用」モードで開き、myStream変数で参照します。
myStreamと文字のエンコード(UTF-8)で初期化された、新しいStreamReaderクラスのインスタンスreaderオブジェクトを作成します。
ReadToEndメソッドでファイルの最後まで読み取り変数resultに格納しておきます。
XElement.Parseメソッドで変数resultの値を文字列として読み込みます。
変数myPersonalImageに要素の値、つまりClaudiaフォルダから取得した画像名を格納します。
変数myClaudiaImageには
要素の値を格納します。クラウディアの画像名が格納されます。
あと、クラウディアのWidth、Heigt、Top、Left属性の値を取得して各変数に格納しておきます。
音声ファイルであるWav属性の値も取得して変数c_Wavに格納しておきます。
同様にClaudiaのフォルダから取得した画像のWidth、Height、Top、Left属性の値も取得して、各変数に格納しておきます。
選択されたXMLファイルは1個で、各要素も属性も1個しか存在しないため、Firstメソッドで、シーケンスの最初の属性を取得しています。
CreateFolderAsyncメソッドでピクチャライブラリ内にClaudiaというサブフォルダを作成します。
CreationCollisionOption.OpenIfExistsと指定すると、同名フォルダがある場合はそのフォルダ名を返し、ない場合は新規に作成します。
GetFileAsyncメソッドで、指定されたファイルの名前を使用して、現在のフォルダから1つのファイルを取得します。
BitmapImageクラスの新しいインスタンスmyBmpを作成します。
SetSourceメソッドにAwait peronalImageFile.OpenReadAsyncと指定して、ファイルの内容を読むために、現在のファイルのランダムアクセスストリームを開き、BitmapSourceのソースイメージに設定します。
新しいImageのインスタンスpersonalImgを作成します。
Widthにp_Width変数の値を、Heightにp_Heightの値を指定します。
SourceプロパティにはmyBmpオブジェクトを指定します。
Marginプロパティには、p_Leftとp_Topの値を指定します。減算している数値は位置合わせの数値です。
ShowAreaという名前のCanvasにperonalImgオブジェクトを追加します。Claudiaフォルダから読み込んだ画像が表示されます。
新しいImageクラスのインスタンスclaudiaImgオブジェクトを作成します。
Widthプロパティにc_Width変数の値を、Heightプロパティにc_Height変数の値を、Marginプロパティにはc_Leftとc_Top変数の値を指定します。
Sourceプロパティには、Imagesフォルダ内の、変数myClaudiaImageが格納しているファイル名を指定します。
MediaElementのSourceプロパティにはWAVフォルダ内で変数c_Wavに格納されている音声ファイルを指定します。
ShowAreaというCanvasにclaudiaImgを追加します。これで、先に追加しておいたClaudiaフォルダの画像の上にクラウディアのイメージが重なって表示されます。
土台となる画像をClaudiaフォルダから読み込まなかった場合は例外が発生します。その際にはErrorShowプロシージャを実行します。
非同期処理で行われるためメソッドの先頭にAsyncを追加します。
01 | Protected Overrides Async Sub OnNavigatedTo(e As Navigation.NavigationEventArgs) |
03 | delTextBlock.Visibility = Windows.UI.Xaml.Visibility.Collapsed |
04 | playButton.IsEnabled = True |
05 | mySelectedFile = DirectCast(e.Parameter, String) |
07 | Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary |
08 | Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("ClaudiaData2", CreationCollisionOption.OpenIfExists) |
09 | Dim myFile = Await mySubFolder.GetFileAsync(mySelectedFile) |
10 | Using myStream As IRandomAccessStream = Await myFile.OpenAsync(FileAccessMode.Read) |
11 | Using reader As StreamReader = New StreamReader(myStream.AsStream, System.Text.Encoding.UTF8) |
12 | result = reader.ReadToEnd |
15 | Dim doc As XElement = XElement.Parse(result) |
16 | Dim myPeronalImage = doc.Descendants("PersonalImage").Value |
17 | Dim myClaudiaImage = doc.Descendants("Image").Value |
18 | Dim c_Width = doc.Descendants("Image").Attributes("Width").First |
19 | Dim c_Height = doc.Descendants("Image").Attributes("Height").First |
20 | Dim c_Top = doc.Descendants("Image").Attributes("Top").First |
21 | Dim c_Left = doc.Descendants("Image").Attributes("Left").First |
22 | Dim c_Wav = doc.Descendants("Image").Attributes("Wav").First.Value |
24 | Dim p_Width = doc.Descendants("PersonalImage").Attributes("Width").First |
25 | Dim p_Height = doc.Descendants("PersonalImage").Attributes("Height").First |
26 | Dim p_Top = doc.Descendants("PersonalImage").Attributes("Top").First |
27 | Dim p_Left = doc.Descendants("PersonalImage").Attributes("Left").First |
28 | Dim personalSubFolder As StorageFolder = Await myStorageFolder.CreateFolderAsync("Claudia", CreationCollisionOption.OpenIfExists) |
29 | Dim peronalImageFile = Await personalSubFolder.GetFileAsync(myPeronalImage) |
30 | Dim myBmp As New BitmapImage |
31 | myBmp.SetSource(Await peronalImageFile.OpenReadAsync) |
32 | Dim personalImg As New Image |
34 | .Width = CDbl(p_Width) |
35 | .Height = CDbl(p_Height) |
37 | .Margin = New Thickness(CDbl(p_Left) - 300, CDbl(p_Top) - 170, 0, 0) |
39 | ShowArea.Children.Add(personalImg) |
40 | Dim claudiaImg As New Image |
42 | .Width = CDbl(c_Width) |
43 | .Height = CDbl(c_Height) |
44 | .Margin = New Thickness(CDbl(c_Left), CDbl(c_Top), 0, 0) |
45 | .Source = New BitmapImage(New Uri("ms-appx:///Images/" & myClaudiaImage)) |
48 | MediaElement1.Source = New Uri("ms-appx:///WAV/" & c_Wav) |
50 | ShowArea.Children.Add(claudiaImg) |
例外が発生した場合の処理
警告メッセージを発生して、処理を抜けます。
非同期処理で行われるためメソッドの先頭にAsyncを追加します。
1 | Private Async Sub ErrorShow() |
2 | Dim myMessage As New MessageDialog("ピクチャフォルダ内のClaudiaサブフォルダ内の画像ではありません。Deleteアイコンでこのファイルを削除してください。") |
3 | Await myMessage.ShowAsync |
Playアイコンがタップされた時の処理
音声を再生します。
1 | Private Sub playButton_Click(sender As Object, e As RoutedEventArgs) Handles playButton.Click |
Deleteアイコンがタップされた時の処理
ピクチャライブラリのClaudiaData2サブフォルダにアクセスします。
メンバ変数mySelectedFileに格納されているXMLファイルを、GetFileAsyncメソッドで取得し、変数myFileで参照します。
DeleteAsyncで取得したファイルを削除します。
ShowAreaという名前のCanvasをクリアします。
「削除しました!」を表示するために、delTextBlockを表示状態にします。
Playアイコンの使用を不可にします。またDeleteアイコンの使用も不可とします。
01 | Private Async Sub delButton_Click(sender As Object, e As RoutedEventArgs) Handles delButton.Click |
02 | Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary |
03 | Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("ClaudiaData2", CreationCollisionOption.OpenIfExists) |
04 | Dim myFile = Await mySubFolder.GetFileAsync(mySelectedFile) |
05 | Await myFile.DeleteAsync() |
06 | ShowArea.Children.Clear() |
07 | delTextBlock.Visibility = Windows.UI.Xaml.Visibility.Visible |
08 | playButton.IsEnabled = False |
09 | delButton.IsEnabled = False |
今回はここまでです。ありがとうございました。
筆者からのお知らせ
筆者はWindowsストアでアプリを公開しています。チャームの検索からWindowsストアを選択して、検索欄に、kuniyasuまたはYakushijiKuniyasuと入力すると、公開されているアプリの一覧が表示されます。上記はどちらも私のアカウントですので、興味のある方は是非ダウンロードして使ってみてください。