近くにある病院の場所をキャラクターが音声で教えてくれるアプリを作る
次に、ソリューション・エクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト2のコードを記述します。
ロジックコードを記述する
リスト2 (MainWindow.xaml.vb)
Option Strict On ‘ コンピュータの地理的位置にアクセスできるようにするクラスの含まれる、Windows.Devices.Geolocation名前空間を ‘ インポートします。 Imports Windows.Devices.Geolocation ‘ Bing Mapsに関するクラスの含まれる、Bing.Maps名前空間をインポートします。 Imports Bing.Maps Imports Windows.UI ‘ アプリケーションウィンドウやウィンドウ対話を作成し管理するサポートと、ウィンドウ上の入力イベントを処理する ‘ クラスの含まれる、Windows.UI.Core名前空間をインポートします。 Imports Windows.UI.Core ‘ 最新のHTTPアプリケーション用のプログラミング インターフェイスを提供するクラスの含まれる、 ‘ System.Net.Http名前空間をインポートします。 Imports System.Net.Http Imports Windows.UI.Popups ‘ HospitalInfoクラス内に文字列型の「病院名」、「住所」プロパティを定義しておきます。 Public Class HospitalInfo Public Property 病院名 As String Public Property 住所 As String End Class Public NotInheritable Class MainPage Inherits Page ‘ 現在の地理的位置にアクセスするクラスである、Geolocatorクラスのメンバー変数myGeolocatorを宣言します。 Private myGeolocator As Geolocator ‘ Windowsランタイムコアイベントメッセージディスパッチャを提供するクラスである、 ‘ CoreDispatcherクラスのメンバー変数、myCoreDispacherを宣言します。 Private myCoreDispacher As CoreDispatcher ‘ YahooのアプリケーションIDで初期化された、メンバー定数変数AppIDを宣言します。 Const AppID As String = " YahooのアプリケーションID" ‘ GoogleのAPI Keyで初期化された、メンバー定数変数GoogleAppIDを宣言します。 Const GoogleAppID As String = " GoogleのAPI Key" Private flag As Boolean = False Private myCoodinatePosition As String = String.Empty Private myAddressCoodinatePosition As String = String.Empty Private myUri As String = String.Empty Private myAddressLatitude As String Private myAddressLongitude As String Private myAddressUri As String ‘ MediaElementクラス型のメンバー変数myMediaを宣言します。 Private myMedia As MediaElement
ページがアクティブになった時の処理
場所にアクセスし、場所が変更された時や、Geolocatorの機能が変更された時に発生する各イベントで、イベントハンドラを実行するDataShowメソッドを実行します。
Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs) DataShow() End Sub
場所にアクセスし、場所が変更された時や、Geolocatorの機能が変更された時に発生する各イベントで、イベントハンドラを実行する処理。
myGeolocatorオブジェクトが作成されていない場合は、新しいGeolocatorクラスのインスタンスmyGeolocatorオブジェクトを作成します。
場所認識の精度レベルを表す、DesiredAccuracy プロパティにはDefaultを指定しておきます。
Default以外にHighがありますが、パフォーマンスが低下する恐れがありますので、Defaultを指定しています。
Window.Current.CoreWindow.Dispatcherで、現在アクティブになっている、ウィンドウの内部コアオブジェクトのイベントディスパッチャを取得して、myCoreDispacherで参照します。
AddHandlerステートメントで、場所が更新された時のPositionChangedイベント時のイベントハンドラ、myGeolocator_PositionChangedを追加します。
同じく、AddHandlerステートメントで、更新された場所を提供するGeolocatorの機能が変更された時に発生する、StatusChanged時のイベントハンドラ、myGeolocator_StatusChangedを追加します。
Private Sub DataShow() If myGeolocator Is Nothing = True Then myGeolocator = New Geolocator myGeolocator.DesiredAccuracy = PositionAccuracy.Default myCoreDispacher = Window.Current.CoreWindow.Dispatcher End If AddHandler myGeolocator.PositionChanged, AddressOf myGeolocator_PositionChanged AddHandler myGeolocator.StatusChanged, AddressOf myGeolocator_StatusChanged End Sub
場所が変更された時の処理
myCoreDispacher.RunAsyncメソッドで、イベントディスパッチャを実行し、ディスパッチされたイベントの結果を非同期に返します。ディスパッチャの優先順位は標準のNormalを指定しています。
緯度と経度のデータや都市の住所データを含めることができるGeoPositionクラス型の変数posを宣言し、PositionChangedイベントに関連付けられた場所データを取得します。
Clearメソッドで、地図内を一度クリアしておきます。
新しいPushpinクラスのインスタンスmyPinオブジェクトを作成します。ピンの背景色を「Crimson」に指定します。
新しいLocationクラスのインスタンスmyLocationオブジェクトを作成します。Locationクラスは、地図上の場所の標高と座標値を含むクラスです。
ブール型のメンバー変数flagの値で条件分岐を行います。FlagがTrueであった場合、つまり、マウスを右クリックして表示される住所を入力するボックスに住所を入力して、「OK」ボタンがクリックされた場合、ということです。その場合は、Locationを、メンバー変数myAddressLatitudeに格納された緯度の値と、myAddressLongitudeに格納された経度の値で初期化します。
それ以外の場合は、現在位置の緯度(pos.Coordinate.Point.Position.Latitude)と経度(pos.Coordinate.Point.Position.Longitude)で初期化します。
MapLayerクラスのSetPositionメソッドで、マップレイヤー内にピンの位置を設定します。
myMapにAddメソッドでピンを追加します。
SetViewメソッドで、指定された中心部に位置、ズーム レベル、方位、およびピッチにマップビューを設定します。この場合myLocationの位置に16レベルでズームインします。
ブール型のメンバー変数flagの値で条件分岐を行います。FlagがTrueであった場合、つまり、現在位置の緯度(pos.Coordinate.Point.Position.Latitude)と経度(pos.Coordinate.Point.Position.Longitude)が取得されている場合の処理です。
メンバー変数myAddressUriに「Yahoo!ローカルサーチAPI」のアドレスを格納します。
引数latにpos.Coordinate.Point.Position.Latitudeの緯度の値を指定して、lonにpos.Coordinate.Point.Position.Longitudeの経度の値を指定します。
AppidにはYahooのアプリケーションIDを指定します。
そうでない場合、つまり、マウスを右クリックして表示される住所を入力するボックスに住所を入力して、「OK」ボタンがクリックされた場合、ということです。その場合は、Locationを、メンバー変数myAddressLatitudeに格納された緯度の値と、myAddressLongitudeに格納された経度の値で初期化します。
新しいHttpClientクラスのインスタンスmyAddressHttpClientオブジェクトを作成します。
HttpClientクラスは、URIで識別されるリソースにHTTP要求を送信し、そのリソースからHTTP応答を受信するための基本クラスが含まれています。
XML要素を表すXElementクラス型変数、xmldocを宣言します。
GetStringAsyncメソッドでmyAddressUriの結果を文字列として返し、変数myCurrentAddressに格納します。
GetStringAsyncメソッドは、指定URIにGET要求を送信し、非同期操作で応答本体を文字列として返すメソッドです。
返される文字列はXML形式になっています。このXMLのルート要素には、名前空間や不要な属性が定義されていて、内容を取得する際の邪魔(-_-;)になりますので、Replace関数で、ルート要素(
XElement.Parseメソッドで置換された結果のXMLが格納されている、myCurrentAddressを文字列として読み込みます。
読み込んだXMLから
要素の内容を取得して、変数myAddressに格納しておきます。新しいStackPanelのインスタンスmyAddressStackPanelオブジェクトを作成します。
Marginプロパティに「5」を指定して余白を設けます。
背景色を「Navy」に指定します。
このStackPanelオブジェクトのインスタンスを、非表示としておきます。
新しいTextBlockのインスタンスmyAddressTextBlockオブジェクトを作成します。文字色を「Red」に指定します。
文字サイズに「24」を指定し、パディングに「5」を指定します。
ブール型のメンバー変数flagの値で条件分岐を行います。FlagがFalse であった場合は(つまり通常の処理をしていた場合)、myAddressTextBlockに変数myAddressと文字列「辺り」を連結して表示します。それ以外の場合は、つまり、マウスを右クリックして表示される住所を入力するボックスに住所を入力して、「OK」ボタンがクリックされた場合、ということです。その場合は、WatermarkTextBoxに入力された値と文字列「辺り」を連結して表示します。
myStackPanelオブジェクトにAddメソッドで住所の設定された、myAddressTextBlockを追加します。
SetValueメソッドでmyAddressStackPanelのZIndexPropertyに20を指定します。myAddressStackPanelが前面に表示されます。
ブール型のメンバー変数flagの値で条件分岐を行います。FlagがFalseであった場合、つまり通常の処理を行っていた場合は、MapLayerクラスのSetPositionメソッドで、マップレイヤー内にmyAddressStackPanelオブジェクトの位置を設定し、Locationを現在位置の緯度と経度で初期化して指定します。それ以外の場合、つまり、マウスを右クリックして表示される住所を入力するボックスに住所を入力して、「OK」ボタンがクリックされた場合、ということです。MapLayerクラスのSetPositionメソッドで、マップレイヤー内にmyAddressStackPanelオブジェクトの位置を設定し、Locationをメンバー変数myAddressLatitudeが格納している緯度とmyAddressLongitudeが格納している経度で初期化して設定します。
MapLayerクラスは、地図上の要素の位置を保持しているマップレイヤーを表すクラスです。
myMapにAddメソッドでmyAddressStackPanelオブジェクトを追加します。
myAddressStackPanelは最初の状態では非表示になっているのでわかりませんが、ピンの位置にStackPanelオブジェクトが表示されることになります。
AddHandlerステートメントでピンをタップした時のイベントハンドラを追加します。
イベントハンドラ内では、myAddressStackPanelオブジェクトを表示状態にします。
AddHandlerステートメントでmyAddressStackPanelをタップした時のイベントハンドラを追加します。イベントハンドラ内では、myAddressStackPanelオブジェクトを非表示状態にします。
ブール型のメンバー変数flagの値で条件分岐を行います。FlagがTrueであった場合、つまり、マウスを右クリックして表示される住所を入力するボックスに住所を入力して、「OK」ボタンがクリックされた場合、ということです。
病院の情報を取得するGoogleのWeb APIのURLを設定します。
「location」には緯度と経度をカンマで区切って格納している、メンバー数myAddressCoodinatePositionの値を指定します。
「radius」には範囲(メートル単位)を指定します。ここでは1000を指定して1Kmとしています。
「types」には、何を目的に検索するかを指定します。ここでは「Hospital」を指定しています。
この「types」には|(パイプ)で区切って複数の値を指定できます。指定できる値の一覧は下記のURLを参照してください。
> https://developers.google.com/places/documentation/supported_types
「Sensor」には場所の要求が位置センサー(GPS など)を使用してデバイスから来たかどうかを示す値を、trueまたはfalseで指定します。ここでは「true」を指定しています。
「language」には「ja」を「key」にはGoogleより取得した「APIKey」を指定します。
「OK」ボタンがクリックされていない場合は、locationに現在位置の緯度と経度をカンマで区切った値を格納している、メンバー変数myCoodinatePositionの値を指定します。
検索結果は最大で20件までの情報を取得して表示します。これらの式を変数myUriに格納しておきます。TitleTextBlockにWatermarkTextBlockに入力された値、または現在位置の住所を格納しているmyAddress変数の値と、文字列「辺り」を連結して表示します。
新しいHttpClientのインスタンスmyHttpClientを作成します。
GetStringAsyncメソッドでGoogleの Web APIの式を格納しているmyUriの内容を読み取り、返ってくるXMLを変数resultHospitalに格納します。
XElement.ParseメソッドでresultHospitalが格納しているXMLの内容を、文字列として読み込みます。
HospitalInfoクラス型である新しいリストのインスタンスmyHospitalInfoオブジェクトを作成します。
Descendantsメソッドで、全ての
変数noの値を1ずつ増加させます。この値は、これから作成する「Webで表示」ボタンの、どのボタンがクリックされたかの判定に使用します。
新しいImageのインスタンスmyImageオブジェクトを作成します。Widthに「70」、Heightに「137」と指定し、Sourceプロパティにソリューション・エクスプローラー内のImagesフォルダ内にある「syoko1.png」を指定します。
新しいStackPanelのインスタンスsyokoStackPanelオブジェクトを作成します。背景色に「DarkGreen」を指定し、AddメソッドでmyImageオブジェクトを追加します。
新しいPushPinクラスのインスタンスhospitalPinオブジェクトを作成します。
背景色に「Crimson」を指定し、Textプロパティに1ずつ増加する変数noの値を指定します。
ピンの表面に連番が表示されます。
地理的位置に関連付けされた緯度と経度で初期化された、新しいLocationクラスのインスタンスhospitalLocationオブジェクトを作成します。
MapLayerクラスのSetPositionメソッドで、マップレイヤー内に病院のピンの位置を設定します。myMapにAddメソッドで病院の位置にピンを追加します。
新しいStackPanelのインスタンスresultStackPanelオブジェクトを作成し、Orientationに「Horizontal」と指定しておきます。
新しいStackPanelのインスタンスmyStackPanelオブジェクトを作成します。
Marginに「5」、背景色に「Navy」を指定し、非表示としておきます。
新しいTextBlockのインスタンスmyNameTextBlockを作成します。
文字色は「Red」、Widthに「400」、文字の回り込みは可、文字サイズは「24」、パディングは「5」と指定します。
Textプロパティには、文字列「病院名」と
新しいTextBlockのインスタンスaddressTextBlockを作成します。
文字色は「Beige」、Widthに「400」、文字の回り込みは可、文字サイズは「20」、パディングは「5」と指定します。
Textプロパティには、文字列「住所」と
HositalInfoクラスの「病院」プロパティに連番と、
新しいButtonのインスタンスmyButtonを作成します。
Contentプロパティに「Webで表示」と指定します。
Tagプロパティに変数noの値を指定します。どのButtonがクリックされたかの判定に使用します。
キャラクタに読み上げさせる文章の内容をメンバー変数readingAddressに格納しておきます。
SetValueメソッドで、myStackPanelのZIndexPropertyに変数noの値を指定します。myStackPanelがPushPinよりも前面に表示されるようになります。
myStackPanelオブジェクトにAddメソッドで、myNameTextBlock、addressTextBlock、myButtonを追加します。
resultStackPanelオブジェクトに、AddメソッドでmyStackPanelオブジェクト、syokoStackPanelオブジェクトを追加します。
resultStackPanelオブジェクトは非表示としておきます。
MapLayerクラスのSetPositionメソッドで、マップレイヤー内にresultStackPanelの位置を設定します。
myMapにAddメソッドでresultStackPanelを追加します。
AddHandlerステートメントで、病院の位置を表すピンがタップされた時のイベントハンドラを追加します。イベントハンドラ内では以下の処理を行います。
resultStackPanelオブジェクトが表示状態になり、病院の情報とキャラクタが表示されます。
メンバー変数myMediaを、MediaElement1で初期化しておきます。
音声機能へのアクセスを提供する、新しいSpeechSynthesizerのインスタンス、synthオブジェクトを作成します。
SynthesizeTextToStreamAsyncメソッドで、指定した文字列から、音声出力を非同期に生成します。
SetSourceメソッドで、指定されたストリームおよびMIME型を使用してSourceプロパティを設定します。Playメソッドで音声を再生します。
音声にどんな言語で、どのような声で喋らすかは、SpeechSynthesizerのVoiceプロパティで参照できます。下記のURLを参照してください。
> http://msdn.microsoft.com/en-us/library/windows.media.speechsynthesis.speechsynthesizer.voice.aspx
上記URLを見るとJapanese JA は性別が「Female」で、名前は「Haruka」という女性が読み上げるようです。
非同期処理で行われるため、イベントハンドラの先頭にAsyncを追加します。
AddHandlerステートメントで、病院の情報を表示した、resultStackPanelがタップされた時のイベントハンドラを追加します。
音声の読み上げを中止します。resultStackPanelオブジェクトが非表示になります。
AddHandlerステートメントで、Buttonがクリックされた時のイベントハンドラを追加します(Webで表示がクリックされた時の処理です)。
クリックされたButtonのTagの値を変数indexに格納します。数値にキャストしたindexの値をmyIndexに格納します。-1しているのは、ピンの表面に表示される連番は1から20まで表示されますが、XML要素のインデックスは0から始まるため-1しています。
変数mySendAddressにmyIndexに位置する
これらの値はUri.EscapeDataStringメソッドでエスケープ表現に変換しておきます。
Windows.System.Launcher.LaunchUriAsyncメソッドで、指定されたURIのURIスキーム名に関連付けられている既定のアプリケーション(この場合はIE11のブラウザ)を起動します。
この記述方法では、Windows ストアの認定の要件「2.4 アプリで提供されるプライマリ エクスペリエンスはアプリ内で行われなければならない」に抵触し、ストアの審査には通りませんが、審査員のコメント欄に、「このアプリの目的は病院の位置をBing Maps上に表示させて、キャラクタに読み上げさせることにあります。ブラウザでの表示はあくまでも補助的手段です。」と記述しておけば、大体認定されますので、お試しください。
Try~Catch~End Tryで例外処理を行っています。例外が発生した場合はErrorShowプロシージャを実行します。
最後にGridView1のItemsSourceプロパティにmyHospitalInfoオブジェクトを追加します。これで、マウスの右クリックをした際に、アプリケーションバー内に病院の一覧が表示されます。
非同期処理で行われるためメソッドの先頭にAsyncを追加します。
Private Async Sub myGeolocator_PositionChanged(sender As Geolocator, args As PositionChangedEventArgs) Dim myLatitude As String = String.Empty Dim myLongitude As String = String.Empty Dim no As Integer = 0 Await myCoreDispacher.RunAsync(CoreDispatcherPriority.Normal, Async Sub() Dim pos As Geoposition = args.Position myMap.Children.Clear() Dim myPin As New Pushpin myPin.Background = New SolidColorBrush(Colors.Crimson) Dim myLocation As Location If flag = True Then myLocation = New Location(CDbl(myAddressLatitude), CDbl(myAddressLongitude)) Else 'Windows 8.1の新形式 myLocation = New Location(CDbl(pos.Coordinate.Point.Position.Latitude), CDbl(pos.Coordinate.Point.Position.Longitude)) End If MapLayer.SetPosition(myPin, myLocation) myMap.Children.Add(myPin) myMap.SetView(myLocation, 16) If flag = False Then myAddressUri = String.Format("http://reverse.search.olp.yahooapis.jp/OpenLocalPlatform/V1/reverseGeoCoder?lat={0}&lon={1}&appid={2}", pos.Coordinate.Point.Position.Latitude, pos.Coordinate.Point.Position.Longitude, AppID) Else myAddressUri = String.Format("http://reverse.search.olp.yahooapis.jp/OpenLocalPlatform/V1/reverseGeoCoder?lat={0}&lon={1}&appid={2}", myAddressLatitude, myAddressLongitude, AppID) End If Dim myAddressHttpClient As New HttpClient Dim myCurrentAddress As String = String.Empty Dim xmldoc As XElement Try myCurrentAddress = Await myAddressHttpClient.GetStringAsync(myAddressUri) myCurrentAddress = myCurrentAddress.Replace("<YDF firstResultPosition=" & ChrW(34) & "1" & ChrW(34) & " totalResultsAvailable=" & ChrW(34) & "1" & ChrW(34) & " totalResultsReturned=" & ChrW(34) & "1" & ChrW(34) & " xmlns=" & ChrW(34) & "http://olp.yahooapis.jp/ydf/1.0" & ChrW(34) & ">", "<YDF>") xmldoc = XElement.Parse(myCurrentAddress) Dim myAddress = xmldoc.Descendants("Address").Value Dim myAddressStackPanel As New StackPanel myAddressStackPanel.Margin = New Thickness(5) myAddressStackPanel.Background = New SolidColorBrush(Colors.Navy) myAddressStackPanel.Visibility = Xaml.Visibility.Collapsed Dim myAddressTextBlock As New TextBlock myAddressTextBlock.Foreground = New SolidColorBrush(Colors.Red) myAddressTextBlock.FontSize = 24 myAddressTextBlock.Padding = New Thickness(5) If flag = False Then myAddressTextBlock.Text = myAddress & " 辺り" Else myAddressTextBlock.Text = WatermarkTextBox1.Text & " 辺り" End If myAddressStackPanel.Children.Add(myAddressTextBlock) myAddressStackPanel.SetValue(Canvas.ZIndexProperty, 20) If flag = False Then 'Windows 8.1の新形式 MapLayer.SetPosition(myAddressStackPanel, New Location(CDbl(pos.Coordinate.Point.Position.Latitude), CDbl(pos.Coordinate.Point.Position.Longitude))) Else MapLayer.SetPosition(myAddressStackPanel, New Location(CDbl(myAddressLatitude), CDbl(myAddressLongitude))) End If myMap.Children.Add(myAddressStackPanel) AddHandler myPin.Tapped, Sub() myAddressStackPanel.Visibility = Xaml.Visibility.Visible End Sub AddHandler myAddressStackPanel.Tapped, Sub() myAddressStackPanel.Visibility = Xaml.Visibility.Collapsed End Sub If flag = True Then myUri = String.Format("https://maps.googleapis.com/maps/api/place/nearbysearch/xml?location={0}&radius=1000&types=hospital|dentist|doctor&sensor=true&language=ja&key={1}", myAddressCoodinatePosition, GoogleAppID) ‘ (B) TitleTextBlock.Text = WatermarkTextBox1.Text & " 辺りの1Km範囲内の病院を表示" Else myCoodinatePosition = pos.Coordinate.Point.Position.Latitude & "," & pos.Coordinate.Point.Position.Longitude myUri = String.Format("https://maps.googleapis.com/maps/api/place/nearbysearch/xml?location={0}&radius=1000&types=hospital|dentist|doctor&sensor=true&language=ja&key={1}", myCoodinatePosition, GoogleAppID) TitleTextBlock.Text = myAddress & " 辺りの1Km範囲内の病院を表示" End If Dim myHttpClient As New HttpClient Dim resultHospital = Await myHttpClient.GetStringAsync(myUri) Dim httpDoc As XElement = XElement.Parse(resultHospital) Dim myHospitalInfo As New List(Of HospitalInfo) For Each result In From c In httpDoc.Descendants("result") Select c no += 1 Dim myImage As New Image With myImage .Width = 70 .Height = 137 .Stretch = Stretch.UniformToFill .Source = New BitmapImage(New Uri("ms-appx:///Images/syoko1.png", UriKind.Absolute)) End With Dim syokoStackPanel As New StackPanel syokoStackPanel.Background = New SolidColorBrush(Colors.DarkGreen) syokoStackPanel.Children.Add(myImage) Dim hospitalPin As New Pushpin hospitalPin.Background = New SolidColorBrush(Colors.Navy) hospitalPin.Text = no.ToString myLongitude = result.Element("geometry").Element("location").Element("lng").Value myLatitude = result.Element("geometry").Element("location").Element("lat").Value Dim hospitalLocation = New Location(CDbl(myLatitude), CDbl(myLongitude)) MapLayer.SetPosition(hospitalPin, hospitalLocation) myMap.Children.Add(hospitalPin) Dim resultStackPanel As New StackPanel resultStackPanel.Orientation = Orientation.Horizontal Dim myStackPanel As New StackPanel myStackPanel.Margin = New Thickness(5) myStackPanel.Background = New SolidColorBrush(Colors.Navy) Dim myNameTextBlock As New TextBlock myNameTextBlock.Foreground = New SolidColorBrush(Colors.Red) myNameTextBlock.Width = 400 myNameTextBlock.TextWrapping = TextWrapping.Wrap myNameTextBlock.FontSize = 24 myNameTextBlock.Padding = New Thickness(5) myNameTextBlock.Text = no.ToString & ":" & "【病院名】=" & result.Element("name").Value Dim addressTextBlock As New TextBlock addressTextBlock.Foreground = New SolidColorBrush(Colors.Beige) addressTextBlock.Width = 400 addressTextBlock.TextWrapping = TextWrapping.Wrap addressTextBlock.FontSize = 20 addressTextBlock.Padding = New Thickness(5) addressTextBlock.Text = "【住所】=" & result.Element("vicinity").Value myHospitalInfo.Add(New HospitalInfo With {.病院名 = no.ToString & ":【病院名】=" & result.Element("name").Value, .住所 = "【住所】=" & result.Element("vicinity").Value}) Dim myButton As New Button With myButton .Content = "Webで表示" .Tag = no.ToString End With Dim readingAddress As String = no.ToString & "ばんめ、病院めいは" & result.Element("name").Value & "です。住所は" & result.Element("vicinity").Value & "です。詳細はウェブで確認してください。" myStackPanel.SetValue(Canvas.ZIndexProperty, no) myStackPanel.Children.Add(myNameTextBlock) myStackPanel.Children.Add(addressTextBlock) myStackPanel.Children.Add(myButton) resultStackPanel.Children.Add(myStackPanel) resultStackPanel.Children.Add(syokoStackPanel) resultStackPanel.Visibility = Xaml.Visibility.Collapsed MapLayer.SetPosition(resultStackPanel, New Location(CDbl(myLatitude), CDbl(myLongitude))) myMap.Children.Add(resultStackPanel) resultStackPanel.SetValue(Canvas.ZIndexProperty, no) AddHandler hospitalPin.Tapped, Async Sub() resultStackPanel.Visibility = Xaml.Visibility.Visible myImage.Visibility = Xaml.Visibility.Visible myMedia = Me.MediaElement1 Dim synth = New Windows.Media.SpeechSynthesis.SpeechSynthesizer Dim stream = Await synth.SynthesizeTextToStreamAsync(readingAddress) myMedia.SetSource(stream, stream.ContentType) myMedia.Play() End Sub AddHandler resultStackPanel.Tapped, Sub() myMedia.Stop() resultStackPanel.Visibility = Xaml.Visibility.Collapsed End Sub AddHandler myButton.Click, Async Sub(mySender As Object, myArgs As RoutedEventArgs) Dim index = DirectCast(mySender, Button).Tag Dim myIndex = CInt(index) - 1 Dim mySendAddress = httpDoc.Descendants("vicinity")(myIndex).Value & " " & httpDoc.Descendants("name")(myIndex).Value Await Windows.System.Launcher.LaunchUriAsync(New Uri("http://www.bing.com/search?q=" & Uri.EscapeDataString(mySendAddress), UriKind.Absolute)) End Sub Next GridView1.ItemsSource = myHospitalInfo Catch ErrorShow() End Try End Sub) End Sub
近くの病院をキャラクターが音声で教えてくれるアプリ
『Windows 8.1+Visual Studio 2013によるWindows ストア・アプリ開発実例集』 第9回のサンプルプログラムです。