お花とクラウディアさんを合成して表示するプログラムを作る

2013年5月8日(水)
薬師寺 国安

Windows ストア空白のページの作成(DataShowPage.xaml)

VS2012のメニューの「プロジェクト(P)/新しい項目の追加(W)」と選択して、左に表示される項目からWindows ストアを選択します。
右に表示されるテンプレートから「空白のページ」を選択します。「名前(N):」にはDataShowPage.xamlと指定して、[追加(A)]ボタンをクリックします。

コントロールの配置

ツールボックスからDataShowPage.xamlのデザイン画面上にコントロールを配置します。Canvasコントロールを1個、TextBlockコントロールを2個、Buttonコントロールを1個配置します。
書き出されるXAMLコードはリスト3、レイアウトは図8のようになります。

リスト3 書き出されたXAMLコード(DataShowPage.xaml)

  • (1)名前がShowAreaという要素を配置しています。
  • (2)タイトルを表示する要素を配置しています。文字色にPinkを指定しています。
  • (3)名前がdelButtonという
  • (4)名前がdelTextBlockという要素を配置し、Textプロパティに「削除しました!」と指定しておきます。文字色にはRedを指定し、最初の状態ではVisibilityにCollapsedを指定して非表示としておきます。
<Page
  x:Class="ClaudiaWithFlower.DataShowPage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="using:ClaudiaWithFlower"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="d">
  <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <Canvas x:Name="ShowArea"  Height="480" Margin="295,186,431,102" Width="640"/>■(1)
    <TextBlock HorizontalAlignment="Left" Height="107" Margin="246,31,0,0" TextWrapping="Wrap" Text="お花とクラウディアちゃん!" VerticalAlignment="Top" Width="818" FontFamily="Meiryo UI" FontSize="72" FontWeight="Bold" Foreground="Pink"/>■(2)
    <Button x:Name="delButton" HorizontalAlignment="Left" Height="92" Margin="543,666,0,0" VerticalAlignment="Top" Width="97" Style="{StaticResource DeleteAppBarButtonStyle}"/>■(3)
    <TextBlock x:Name="delTextBlock" HorizontalAlignment="Left" Height="125" Margin="246,310,0,0" TextWrapping="Wrap" Text="削除しました!" VerticalAlignment="Top" Width="730" FontFamily="Meiryo UI" FontSize="100" FontWeight="Bold" Foreground="Red" Visibility="Collapsed"/>■(4)
  </Grid>
</Page>
図8:各種コントロールを配置した(クリックで拡大)

次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト4のコードを記述します。

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

リスト4 (MainWindow.xaml.vb)

Option Strict On

シーケンシャルアクセスストリームおよびランダムアクセスストリームに対する読み込みと書き込みのサポートを提供するクラスの含まれる、Windows.Storage.Streams名前空間をインポートします。

Imports Windows.Storage.Streams

ファイルやフォルダおよびアプリケーションの設定を管理するクラスの含まれる、Windows.Storage名前空間をインポートします。

Imports Windows.Storage

コンテキストメニューおよびメッセージダイアログのサポートを提供するクラスの含まれる、Windows.UI.Popups名前空間をインポートします。

Imports Windows.UI.Popups

ClaudiaInfoクラス内で文字列型のClaudiaImageプロパティを定義しておきます。

Public Class ClaudiaInfo
  Property ClaudiaImage As String
  End Class

FlowerInfoクラス内で、文字列型のFlower、f_Width、f_Heightプロパティを定義しておきます。

Public Class FlowerInfo
  Property Flower As String
  Property f_Width As String
  Property f_Height As String
End Class

Public NotInheritable Class MainPage
  Inherits Page

ファイルを表すStorageFileクラス型のclaudiaImageとflowerImageメンバ変数を宣言します。

  Dim claudiaImage As StorageFile
  Dim flowerImage As StorageFile

Imageクラス型のメンバ変数myFlowerImageとmyClaudiaImageを宣言します。

  Dim myFlowerImage As Image
  Dim myClaudiaImage As Image

オブジェクトに複数の変換操作を適用するCompositeTransformクラス型のメンバ変数、myTransとmyFlowerTransを宣言します。

  Dim myTrans As CompositeTransform
  
  Dim myFlowerTrans As CompositeTransform
  Dim myClaudiaFileName As String

XMLを表すXElementクラス型のメンバ変数xmldocを宣言します。

 Dim xmldoc As XElement

 Dim claudiaImageFileName As String

ファイルを表すStorageFileクラス型のメンバ変数myPersonalImageを宣言します。

 Dim myPeronalImage As StorageFile

 Dim FlowerFile As String

XMLを表すXElementクラス型のメンバ変数flowerXmlを宣言します。

 Dim flowerXml As XElement
 
 Dim Index As Integer
 Dim flowerIndex As Integer

ページがアクティブになった時の処理。

XMLファイルが存在する場合はListBoxにXMLファイルの一覧を表示し、クラウディアや花の画像をListBoxに表示するDataShowプロシージャを実行します。

  Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
    DataShow()
    MyBase.OnNavigatedTo(e)
End Sub

XMLファイルが存在する場合はListBoxにXMLファイルの一覧を表示し、クラウディアや花の画像をListBoxに表示する処理。

ピクチャライブラリにアクセスします。
CreateFolderAsyncメソッドで、ピクチャライブラリ内にFlowerAndClaudiaというサブフォルダを作成します。CreationCollisionOption.OpenIfExistsを指定すると、既に同名フォルダが存在する場合はフォルダ名を返し、ない場合は新規に作成します。

GetFilesAsyncメソッドでFlowerAndClaudiaサブフォルダ内のファイルの一覧を取得します。
Countプロパティでファイルの個数を取得し、ファイルが存在する場合は以下の処理を実行します。

文字列型の新しいリストであるmyXmlListを作成します。
FlowerAndClaudiaサブフォルダ内のファイルコレクション内を変数fileResutで反復処理しながら、リストであるmyXmlListにAddメソッドでファイル名を追加していきます。
fileResult.Pathで取得されるファイル名は絶対パス付きファイル名になりますので、Path.GetFileNameWithoutExtension(fileResult.Path)として、パスと拡張子を除いたファイル名を取得し、拡張子となる”.xml”と連結します。
fileListBoxのItemsSourceプロパティにmyXmlListオブジェクトを追加します。
これで、FlowerWithClaudiaサブフォルダ内にXMLファイルが存在する場合はListBoxに一覧表示されます。

XElement.LoadメソッドでXML文書ファイル(claudia.xml)を読み込みます。
ClaudiaInfoクラス型の新しいリストであるmyClaudiaInfoを作成します。
Descendantsメソッドで全ての子孫要素である要素のコレクションに対して、要素名を変数resultに格納しながら反復処理を行います。
ClaudiaInfoクラスのClaudiaImageプロパティに画像を格納している”ms-appx:///Images/”と要素の属性”small”の値を連結して指定し、AddメソッドでmyClaudiaInfoオブジェクトに追加していきます。

claudiaListBoxのItemsSourceプロパティにmyClaudiaInfoオブジェクトを指定します。これで、ListBoxにクラウディアの画像一覧が表示されます。

XElement.LoadメソッドでXML文書ファイル(flower.xml)を読み込みます。
FlowerInfoクラス型の新しいリストであるflowerListを作成します。
Descendantsメソッドで全ての子孫要素である要素のコレクションに対して、要素名を変数resultに格納しながら反復処理を行います。
FlowerInfoクラスのf_WidthプロパティにDouble型にキャストした要素の属性”Width”の値を指定します。
F_HeightプロパティにDouble型にキャストした要素の属性”Height”の値を指定します。
画像を格納している”ms-appx:///Images/”と要素の値を連結して指定し、AddメソッドでFlowerListオブジェクトに追加していきます。

flowerListBoxのItemsSourceプロパティにflowerListオブジェクトを指定します。これで、ListBoxに花の画像一覧が表示されます。

  Private Async Sub DataShow()
    Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary
    Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("FlowerAndClaudia", CreationCollisionOption.OpenIfExists)
    Dim myFile = Await mySubFolder.GetFilesAsync()
    If myFile.Count > 0 Then
      Dim myXmlList As New List(Of String)
      For Each fileResult As StorageFile In myFile
        myXmlList.Add(Path.GetFileNameWithoutExtension(fileResult.Path) & ".xml")
      Next
      fileListBox.ItemsSource = myXmlList
    Else
      fileListBox.SelectedIndex = -1
      fileListBox.ItemsSource = Nothing
    End If
 
    xmldoc = XElement.Load("claudia.xml")
    Dim myClaudiaInfo As New List(Of ClaudiaInfo)
    For Each result In From c In xmldoc.Descendants("Item") Select c
      With myClaudiaInfo
        .Add(New ClaudiaInfo With {.ClaudiaImage = "ms-appx:///Images/" & result.Attribute("small").Value})
      End With
    
    Next
    claudiaListBox.ItemsSource = myClaudiaInfo
 
    flowerXml = XElement.Load("flower.xml")
    Dim flowerList As New List(Of FlowerInfo)
    For Each result In From c In flowerXml.Descendants("Flower") Select c
      With flowerList
        .Add(New FlowerInfo With {.f_Width = CStr(CInt(result.Attribute("Width").Value) / 10), .f_Height = CStr(CInt(result.Attribute("Height").Value) / 10), .Flower = "ms-appx:///Images/" &result.Value})
      End With
    Next
    flowerListBox.ItemsSource = flowerList
  End Sub

クラウディアの画像が選択された時の処理

クラウディアの画像が選択された時は、花の表示されているListBoxを選択可能にします。
メンバ変数claudiaImageFileNameに、claudiaListBoxから選択された項目のインデックスに対応する、要素の属性”Large”の値を格納し、画面にクラウディアを表示して、ピンチで拡大縮小、ドラッグを可能にするclaudiaShowプロシージャを実行します。

  Private Sub claudiaListBox_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles claudiaListBox.SelectionChanged
    Try
      If claudiaListBox.SelectedIndex >= 0 Then
        flowerListBox.IsEnabled = True
      Else
        flowerListBox.IsEnabled = False
      End If
 
      claudiaImageFileName = xmldoc.Descendants("Item")(claudiaListBox.SelectedIndex).Attribute("Large").Value 
       claudiaShow()
    Catch
      Exit Sub
    End Try
  End Sub

花の画像が選択された時の処理

花の画像が選択された時は[Save]アイコンの使用を可能にします。
メンバ変数FlowerFileに、flowerListBoxから選択された項目のインデックスに対応する、要素の値を格納し、画面に花を表示して、ピンチで拡大縮小、ドラッグを可能にするFlowerShowプロシージャを実行します。

  Private Sub flowerListBox_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles flowerListBox.SelectionChanged
    Try
      If flowerListBox.SelectedIndex >= 0 Then
        saveButton.IsEnabled = True
      Else
        saveButton.IsEnabled = False
      End If
      FlowerFile = flowerXml.Descendants("Flower")(flowerListBox.SelectedIndex).Value
      FlowerShow()
    Catch
      Exit Sub
    End Try
  End Sub
薬師寺国安事務所

薬師寺国安事務所代表。Visual Basic プログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。1997年に薬師寺聖とコラボレーション・ユニット PROJECT KySS を結成。2003年よりフリーになり、PROJECT KySS の活動に本格的に参加、.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。Windows Phoneアプリ開発を経て、現在はWindows ストア アプリを多数公開中

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)。Microsoft MVP for Development Platforms-Windows Platform Development (Oct 2014-Sep 2015)。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

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