パノラマページを作成する(後編)

2011年7月22日(金)
PROJECT KySS
■ページが読み込まれた時の処理
ListBox1に「場所」の一覧を表示するAddNameプロシージャを実行します。
ListBox2に「曲名」の一覧を表示するAddSongTitleプロシージャを実行します。
    Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles Me.Loaded
      AddName()
      AddSongTitle()
  End Sub

■ListBox1に「場所」の一覧を表示する処理
文字列型の新しいリストであるaddressNameを宣言します。
ReadXmldocクラスのインスタンスmyReadXmldocでAddress関数を呼び出します。Descendantsメソッドで取得した<場所>要素のコレクションに対して、各要素を変数 result に格納しながら、AddメソッドでaddressNameリストに<場所>要素の内容を追加していきます。
ListBox1のItemsSourceプロパティに「場所」の追加されたaddressNameオブジェクトを指定します。
  Private Sub AddName()
    Dim addressName As New List(Of String)
    For Each result In From c In myReadXmldoc.Address.Descendants("場所") Select c
      addressName.Add(result.Value)
    Next
    ListBox1.ItemsSource = addressName
  End Sub

■ListBox2に「曲名」の一覧を表示する処理
文字列型の新しいリストであるsongTitleを宣言します。
ReadXmldocクラスのインスタンスmyReadXmldocでseiSong関数を呼び出します。Descendantsメソッドで取得した<Music>要素のコレクションに対して、各要素を変数 result に格納しながら、AddメソッドでsongTitleリストに<Music>要素の内容を追加していきます。
ListBox2のItemsSourceプロパティに「曲名」の追加されたsongTitleオブジェクトを指定します。
  Private Sub AddSongTitle()
    Dim songTitle As New List(Of String)
    For Each result In From c In myReadXmldoc.seiSong.Descendants("Music") Select c
      songTitle.Add(result.Value)
    Next
    ListBox2.ItemsSource = songTitle
  End Sub

■「場所」が選択された時の処理
NavigationService.NavigateメソッドでBingMap.xamlに遷移します。UriKind.Relativeとし相対URIで指定します。その際、URL の最後に「? キーワード = 遷移先に渡す文字列」という形で引数を付けて、遷移先のページに文字データを渡しています。ここではIndexというキーワードにListBox1より選択された項目のインデックスを指定しています。
  Private Sub ListBox1_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles ListBox1.SelectionChanged
    Dim myIndex As String = ListBox1.SelectedIndex.ToString
    NavigationService.Navigate(New Uri("/BingMap.xaml?Index=" & myIndex, UriKind.Relative))
  End Sub

■「曲名」が選択された時の処理
NavigationService.NavigateメソッドでseiSong.xamlに遷移します。UriKind.Relativeとし相対URIで指定します。その際、URL の最後に「? キーワード = 遷移先に渡す文字列」という形で引数を付けて、遷移先のページに文字データを渡しています。ここではIndexというキーワードにListBox2より選択された項目のインデックスを指定しています。
  Private Sub ListBox2_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles ListBox2.SelectionChanged
    Dim myIndex As String = ListBox2.SelectedIndex.ToString
    NavigationService.Navigate(New Uri("/seiSong.xaml?Index=" & myIndex, UriKind.Relative))
  End Sub
End Class

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

リスト6 Mapに地図を表示する処理 (BingMaps.xaml.vb)

Option Strict On
Imports System.Xml.Linq

場所にアクセスできるクラスの含まれる、System.Device.Location名前空間をインポートしておきます。
Imports System.Device.Location

Windows PhoneのためのBing Maps Silverlightクラスの含まれる、Microsoft.Phone.Controls.Maps名前空間をインポートしておきます。
Imports Microsoft.Phone.Controls.Maps

Partial Public Class BingMaps
  Inherits PhoneApplicationPage

~コード略~

ReadXmldocクラスの新しいインスタンスmyReadXmldocオブジェクトをメンバ変数として宣言します。
  Dim myReadXmldoc As New ReadXmldoc

■画面の遷移で移動した時に最初に呼ばれるイベント
ここで、MainPage.xamlから渡された文字データを受け取ります。文字データはNavigationContextのQueryStringにDictionary として提供されます。送信時のキーワード(この場合Index)を基に渡された文字列情報を、myParam(“Index”)として取得します。
myParam(“Index”)の値を数値に変換して、変数Indexに格納します。
ReadXmldocクラスのインスタンスmyReadXmldocでAddress関数を呼び出します。Descendantsメソッドで、変数Indexに該当する<場所>要素の値を取得し、変数myAddressに格納します。
同じく、変数Indexに該当する<場所>要素の属性”緯度”の値を取得し、変数myLatitudeに格納します。
同じく、変数Indexに該当する<場所>要素の属性”経度”の値を取得し、変数myLongitudeに格納します。
x:NameがPageTitleというTextBlockにmyAddressの値を表示します。場所の名前が表示されます。
地図を移動させるには、MapのCenterプロパティに、GeoCoordinateメソッドにダブル型の緯度と経度を引数で渡した値を指定します。Zoom Levelプロパティに10を指定します。ZoomLevelプロパティを指定しないと地図が表示されませんので注意してください。
PushPinクラスの新しいインスタンスmyPinオブジェクトを生成します。Locationプロパティに、GeoCoordinateメソッドを使って緯度と経度を指定します。ContentプロパティにはmyAddress変数の値を指定します。ピン上に住所が表示されます。緯度と経度とContentの指定されたmyPinオブジェクトをAddメソッドでMapに追加します。これでピンが指定した位置に立ちます。
  Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs)
    Dim myParam As IDictionary(Of String, String) = Me.NavigationContext.QueryString
    Dim Index As Integer = Integer.Parse(myParam("Index"))
    Dim myAddress As String = myReadXmldoc.Address.Descendants("場所")(Index).Value

    Dim myLatitude As String = myReadXmldoc.Address.Descendants("場所")(Index).Attribute("緯度").Value
    Dim myLongitude As String = myReadXmldoc.Address.Descendants("場所")(Index).Attribute("経度").Value
    PageTitle.Text = myAddress
    Map1.Center = New GeoCoordinate(Double.Parse(myLatitude), Double.Parse(myLongitude))
    Map1.ZoomLevel = 10

    Dim myPin As New Pushpin
    myPin.Location = New GeoCoordinate(Double.Parse(myLatitude), Double.Parse(myLongitude))
    myPin.Content = myAddress  
    Map1.Children.Add(myPin)
    MyBase.OnNavigatedTo(e)
  End Sub

■エミュレーターのBack(←)ボタンのイベントを上書きする処理
エミュレーターの持っている本来のBack処理を、e.Cancel=Trueで無効とします。
NavigationService.NavigateメソッドでMainPage.xamlに遷移します。
このBackボタンのイベントを上書きする処理を記述していないと、エミュレーターのBack(←)をクリックした際エラーが発生しますので、注意してください。
Protected Overrides Subと入力すると、インテリセンス機能が働き、イベントの一覧が表示されますので、その中から選択してください。
  Protected Overrides Sub OnBackKeyPress(ByVal e As System.ComponentModel.CancelEventArgs)
    e.Cancel = True
    NavigationService.Navigate(New Uri("/MainPage.xaml", UriKind.Relative))
    MyBase.OnBackKeyPress(e)
  End Sub

■[道路を表示中]ボタンをクリックした時の処理
Button1のContextの値で条件分岐を行います。「道路を表示中」のボタンをクリックした場合は、MapのモードがAerialModeの「航空写真」モードになります。Buttonの文字が「航空写真」に変わります。
「航空写真」のボタンをクリックした場合は、MapのモードがRoadModeの「道路表示」モードになります。Buttonの文字が「道路を表示中」に変わります。
  Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
    Select Case Button1.Content.ToString
    Case "道路を表示中"
      Map1.Mode = New AerialMode
      Button1.Content = "航空写真"
    Case "航空写真"
      Map1.Mode = New RoadMode
      Button1.Content = "道路を表示中"
    End Select
  End Sub
End Class

四国のSOHO。薬師寺国安(VBプログラマ)と、薬師寺聖(デザイナ、エンジニア)によるコラボレーション・ユニット。1997年6月、Dynamic HTMLとDirectAnimationの普及を目的として結成。共同開発やユニット名義での執筆活動を行う。XMLおよび.NETに関する著書や連載多数。最新刊は「Silverlight実践プログラミング」両名とも、Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。http://www.PROJECTKySS.NET/

連載バックナンバー

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

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

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

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