緊急時に対応する救急指定病院の検索アプリを作る

2013年8月15日(木)
薬師寺 国安

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

XElement.LoadメソッドでXML文書ファイル(pref.xml)を読み込みます。

文字列型の新しいリストであるprefListオブジェクトを作成します。

Descendantsメソッドですべての子孫要素の内容を変数resultに格納しながら、以下の処理を行います。

AddメソッドでprefListオブジェクトに要素の内容を追加していきます。

prefComboBoxのItemsSourceプロパティにprefListオブジェクトを指定します。これで選択ボックスに都道府県の一覧が表示されます。

  Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
xmldoc = XElement.Load("pref.xml")
  Dim prefList As New List(Of String)
  For Each result In From c In xmldoc.Descendants("都道府県") Select c
prefList.Add(result.Value)
  Next
prefComboBox.ItemsSource = prefList
  End Sub

選択ボックスから任意の都道府県名が選択された時の処理

メンバ変数prefNameにprefComboBoxから選択した都道府県名を格納しておきます。

  Private Sub prefComboBox_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles prefComboBox.SelectionChanged
prefName = prefComboBox.SelectedItem.ToString
  End Sub

「Yes」ボタンがクリックされた時の処理

都道府県名が選択され、市区町村名が入力された場合の処理です。

変数myUriに、BingのUrlの引数qにエスケープ表現に変換した都道府県名と、エスケープ表現に変換した市区町村名、それにエスケープ表現に変換した「救急指定病院」という文字列を指定し、formatにrssと指定すると、検索した内容をRSSで返してくれます。このURLを格納します。

例えば
http://www.bing.com/search?q=Windows8&go=&form=QBLH&filt=all&format=rss
で表示されるブラウザの画面で、マウスの右クリックで表示されるメニューから「ソースの表示」でソースを表示させ、拡張子を.xmlで書き出し、ブラウザで表示すると図6のようなXMLを返します。このXMLの赤で囲った要素を取りだします。

図6:Windows8を指定して返されたRSSのXMLの構造(クリックで拡大)

新しいHttpClientのインスタンスmyHttpClientオブジェクトを作成します。GetStringAsyncメソッドで、myUriから結果XMLを取得して、変数resultXmlに格納しておきます。

XElement.ParseメソッドでresultXmlの内容を文字列として読み込みます。

HositalInfoクラスの新しいリストである、myHospitalInfoオブジェクトを作成します。

Descendantsメソッドで、すべての子孫要素に対して、その内容を変数resultに格納しながら、以下の処理を行います。HospitalIfoクラスのpubDateプロパティに要素の内容から16文字分を取りだして指定します。
titleプロパティに要素の値を、descriptionプロパティに<description>要素の値を、linkプロパティに<link />要素の値を指定して、Addメソッドで、myHospitalInfoオブジェクトに追加していきます。</description>

GridViewのItemsSourceプロパティにmyHospitalInfoオブジェクトを指定し、AppBarとGridViewが表示状態、Frameが非表示状態となるbackButton_Clickイベントを実行します。引数にはNothingを指定します。

都道府県名が選択されず、市区町村名が入力されていない場合は、警告メッセージを表示します。

非同期処理で行われるため、メソッドの先頭にAsyncを追加します。

  Private Async Sub okButton_Click(sender As Object, e As RoutedEventArgs) Handles okButton.Click
 
    If prefComboBox.SelectedIndex>= 0 AndAlso WaterTextBox1.Text <>String.Empty Then
      Dim myUri = String.Format("http://www.bing.com/search?q={0}&go=&form=QBLH&filt=all&format=rss", Uri.EscapeDataString(prefName) + Uri.EscapeDataString(WaterTextBox1.Text) + Uri.EscapeDataString("救急指定病院"))
      Dim myHttpClient As New HttpClient
      Dim resultXml = Await myHttpClient.GetStringAsync(myUri)
 
      Dim doc As XElement = XElement.Parse(resultXml)
      Dim myHospitalInfo As New List(Of HospitalInfo)
      For Each result In From c In doc.Descendants("item") Select c
  myHospitalInfo.Add(New HospitalInfo With {.pubDate = result.Element("pubDate").Value.Substring(0, 16), .title = result.Element("title").Value, .description = result.Element("description").Value, .link = result.Element("link").Value})
      Next
      GridView1.ItemsSource = myHospitalInfo
  backButton_Click(Nothing, Nothing)
    Else
      Dim message As New MessageDialog("都道府県及び市区町村を指定してください。")
      Await message.ShowAsync
      Exit Sub
    End If
  End Sub

GridViewに表示された、救急指定病院の情報を表示したタイルが選択された時の処理

AppBar1を非表示、myFrameを表示、GridView1を非表示とします。
変数myUrlに、GridViewから選択された項目を、DirectCastでHospitalInfoクラスにキャストして、そのlinkプロパティの値を取得して格納します。

PCの解像度によってmyFrameの幅と高さを指定します。1920×1080はFHD(フルHD)で、今主流の解像度です。1371×771は筆者の持っているSony VAIO Duo 11の解像度です。
VAIO Duo 11はFHDのはずなのですが、解像度を取得すると1371×771が返ってきます。不思議です(-_-;)。1366×768は筆者のSurface RTの解像度です。それ以外の解像度、例えば1024×768の場合はmyFrameの幅を950、高さを700と指定しています。しかし、この解像度を取得して画面サイズを変更させる方法は、お勧めできません。XAML内の要素を で括る方法をおすすめします。

変数myUrlを引数にしてWebBrowserPageに遷移します。

  Private Sub GridView1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles GridView1.SelectionChanged
    Try
      AppBar1.Visibility = Windows.UI.Xaml.Visibility.Collapsed
  myFrame.Visibility = Windows.UI.Xaml.Visibility.Visible
      GridView1.Visibility = Windows.UI.Xaml.Visibility.Collapsed
      Dim myUrl As String = DirectCast(GridView1.SelectedItem, HospitalInfo).link
      Dim myWidth = CInt(Window.Current.CoreWindow.Bounds.Width)
      Dim myHeight = CInt(Window.Current.CoreWindow.Bounds.Height)
      If myWidth = 1920 AndAlsomyHeight = 1080 Then
  myFrame.Width = 1850
  myFrame.Height = 1080
  ElseIfmyWidth = 1371 AndAlsomyHeight = 771 Then
  myFrame.Width = 1080
  myFrame.Height = 700
  ElseIfmyWidth = 1366 AndAlsomyHeight = 768 Then
  myFrame.Width = 1080
  myFrame.Height = 700
      Else
  myFrame.Width = 950
  myFrame.Height = 700
      End If
  myFrame.Navigate(GetType(WebBrowserPage), myUrl)
    Catch
  myFrame.Visibility = Windows.UI.Xaml.Visibility.Collapsed
    End Try
  End Sub

戻る(←)アイコンがタップされた時の処理

AppBar1を表示、GridView1を表示状態にし、myFrameを非表示にします。タイルの画面が表示されます。

  Private Sub backButton_Click(sender As Object, e As RoutedEventArgs) Handles backButton.Click
    AppBar1.Visibility = Windows.UI.Xaml.Visibility.Visible
    GridView1.Visibility = Windows.UI.Xaml.Visibility.Visible
myFrame.Visibility = Windows.UI.Xaml.Visibility.Collapsed
  End Sub
End Class

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

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

リスト4 (WebBrowserPage.xaml.vb)

Public NotInheritable Class WebBrowserPage
  Inherits Page

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

PCの解像度によってWebBrowser1の幅と高さを指定します。Myframeの時の繰り返しになりますが、1920×1080はFHD(フルHD)です。1371×771は筆者の持っているSony VAIO Duo 11の解像度、1366×768は筆者のSurface RTの解像度です。それ以外の解像度、例えば1024×768の場合はWebView1の幅を950、高さを700と指定しています。しかし、この解像度を取得して画面サイズを変更させる方法は、お勧めできません。XAML内の要素を で括る方法をお勧めします。
MainPage.xamlより送られた値は、e.Parameterで取得できます。これはObject型であるため、DirectCastで文字列にキャストし、変数myUriに格納します。
WebBrowser1のSourceプロパティにmyUriで初期化された、新しいUriオブジェクトを指定します。これで、WebBrowser1内に、選択された救急指定病院の情報が表示されます。

  Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
    Dim myWidth = CInt(Window.Current.CoreWindow.Bounds.Width)
    Dim myHeight = CInt(Window.Current.CoreWindow.Bounds.Height)
    If myWidth = 1920 AndAlsomyHeight = 1080 Then
WebBrowser1.Width = 1850
WebBrowser1.Height = 1080
ElseIfmyWidth = 1371 AndAlsomyHeight = 771 Then
WebBrowser1.Width = 1080
WebBrowser1.Height = 700
ElseIfmyWidth = 1366 AndAlsomyHeight = 768 Then
WebBrowser1.Width = 1080
WebBrowser1.Height = 700
    Else
WebBrowser1.Width = 950
WebBrowser1.Height = 700
    End If
    Dim myUri As String = DirectCast(e.Parameter, String)
WebBrowser1.Source = New Uri(myUri, UriKind.Absolute)
  End Sub
End Class

アイコンの作成

ソリューションエクスプローラーのAssetsフォルダ内には、4つのpngファイルが入っています(表1)。

表1:Assetsフォルダ内に入っているpngファイルの種類

ファイル名 サイズ
Logo.png 150×150
SmallLogo.png 30×30
SplashScreen.png 620×300
StoreLogo.png 50×50

表1の画像はデフォルトでは、□に×の画像になっています。ストアの審査では、このままの画像では審査に受かりませんので、4種類のアイコンを作る必要があります。このサンプルは実際にストアで審査の通ったアプリですので、Assetsフォルダ内には筆者の作成したアイコンが収められていますので、見てみてください。

SplashScreen.pngはアプリを起動した際に、一瞬最初に表示される画像です。スタート画面にピン止めされる画像はデフォルトでは150×150のLogo.pngが使用されます。これを長方形の画像にしたい場合は、310×150サイズのpng画像を作成し、WideLogo.png(任意の名前でOK)としてAssetsフォルダに追加しておきます。
詳細については、「自分の現在位置を取得して表示するサンプルプログラム」の記事を参照してください。

今回はここまでです。ありがとうございました。

薬師寺国安事務所

薬師寺国安事務所代表。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メルマガ会員のサービス内容を見る

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