連載 :
Windows Phone Tips集Bing APIを使ってWeb検索とImage検索を実装する
2011年10月17日(月)

次に、MainPage.xamlを展開して表示される、MainPage.xaml.vbをダブルクリックして、リスト3のコードを記述します。
ロジックコードを記述する
リスト3 (MainPage.xaml.vb)
Option Strict On
Imports System.Xml.Linq
Imports System.Net
WebInfoクラス内にTitle、Description、Urlのプロパティを定義しておきます。これは[Web検索]時に使用されます。
Public Class WebInfo
Property Title As String
Property Description As String
Property Url As String
End Class
ImageInfoクラス内にTitle、MediaUrl、Urlのプロパティを定義しておきます。これは[Image検索]時に使用されます。
Public Class ImageInfo
Property Title As String
Property MediaUrl As String
Property Url As String
End Class
Partial Public Class MainPage
Inherits PhoneApplicationPage
' Constructor
Public Sub New()
InitializeComponent()
End Sub
定数変数myAppIDを宣言し、値に「Bing Developer Center で取得したAppID」を指定します。
Const AppID As String = "Bing Developer Center で取得したApplicationID"
Boolean型のメンバ変数flagを宣言します。
Dim flag As Boolean = False
[OK]ボタンがクリックされた時の処理
webRadioButtonにチェックが付いている場合は、flagメンバ変数にFalseを指定します。
Setvalue メソッドで、ListBox(resultListBox) の ItemTemplateProperty に、Web 検索用として定義しておいた、WebListBoxTemplate を指定します。
API へのリクエストは、検索キーワードや検索対象ソースなどの条件を下記のような URL で指定します。(REST)
Dim myUri = String.Format("http://api.search.live.net/xml.aspx?Appid={0}&query={1}&sources=web&web.count=20", AppID, TextBox1.Text)
今回はWeb検索としますので、sourcesにwebと指定します。
このリクエストで返ってくる結果 XML には、web という接頭辞が付加されています(図10参照)ので、XNamespace オブジェクトを作成して文字列を割り当てます。これにより、名前空間とローカル名を結合できます。
新しいWebClientのインスタンスmyWebClientオブジェクトを生成します。DownloadStringAsyncメソッドで、Uri として指定したリソースをダウンロードします。
AddHandler メソッドでダウンロードが完了した DownloadStringCompleted イベントに、イベント ハンドラーを追加します。イベント ハンドラー内では、ダウンロードされた文字列としての結果 XML を、Parse メソッドで読み込みます。Descendants メソッドで、子孫要素である名前空間を結合した全ての <WebResult> 要素のコレクションに対して、各要素を変数 result に格納しながら、WebInfo クラスの「Title」、「Description」、「Url」プロパティに、名前空間を結合した、<Title>、< Description >、<Url> 要素の値を指定し、WebInfo クラスの新しいリストとして作成した、myWebInfo オブジェクトに追加していきます。
ListBox(resultListBox) の ItemSource プロパティに myWebInfo オブジェクトを指定すると、Webの検索結果が ListBox 内に表示されます。
次に「Image検索」ラジオボタンがチェックされた場合の処理です。
imageRadioButtonにチェックが付いている場合は、flagメンバ変数にTrueを指定します。
Setvalue メソッドで、ListBox(resultListBox) の ItemTemplateProperty に、Image 検索用として定義しておいた、ImageListBoxTemplate を指定します。
API へのリクエストは、検索キーワードや検索対象ソースなどの条件を下記のような URL で指定します。(REST)
Dim myUri = String.Format("http://api.search.live.net/xml.aspx?Appid={0}&query={1}&sources=image&web.count=20", AppID, TextBox1.Text)
今回はImage検索としますので、sourcesにimageと指定します。
このリクエストで返ってくる結果 XML には、mms という接頭辞が付加されています(図10参照)ので、XNamespace オブジェクトを作成して文字列を割り当てます。これにより、名前空間とローカル名を結合できます。
新しいWebClientのインスタンスmyWebClientオブジェクトを生成します。DownloadStringAsyncメソッドで、Uri として指定したリソースをダウンロードします。
AddHandler メソッドでダウンロードが完了した DownloadStringCompleted イベントに、イベント ハンドラーを追加します。イベント ハンドラー内では、ダウンロードされた文字列としての結果 XML を、Parse メソッドで読み込みます。Descendants メソッドで、子孫要素である名前空間を結合した全ての <ImageResult> 要素のコレクションに対して、各要素を変数 result に格納しながら、ImagebInfo クラスの「Title」、「MediaUrl」、「Url」プロパティに、名前空間を結合した、<Title>、< MediaUrl >、<Url> 要素の値を指定し、ImageInfo クラスの新しいリストとして作成した、myImageInfo オブジェクトに追加していきます。
ListBox(resultListBox) の ItemSource プロパティに myImageInfo オブジェクトを指定すると、Imageの検索結果が ListBox 内に表示されます。
Private Sub Button1_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
If webRadioButton.IsChecked = True Then
flag = False
resultListBox.SetValue(ListBox.ItemTemplateProperty, Resources("WebListBoxTemplate"))
Dim myUri = String.Format("http://api.search.live.net/xml.aspx?Appid={0}&query={1}&sources=web&web.count=20", AppID, TextBox1.Text)
Dim webNS As XNamespace = "http://schemas.microsoft.com/LiveSearch/2008/04/XML/web"
Dim myWebClient As New WebClient
myWebClient.DownloadStringAsync(New Uri(myUri, UriKind.Absolute))
AddHandler myWebClient.DownloadStringCompleted, Sub(resultdSender As Object, resultArgs As DownloadStringCompletedEventArgs)
Dim xmldoc As XElement = XElement.Parse(resultArgs.Result)
Dim myWebInfo As New List(Of WebInfo)
For Each result In From c In xmldoc.Descendants(webNS + "WebResult") Select c
With myWebInfo
.Add(New WebInfo With {.Title = result.Element(webNS + "Title").Value,
.Description = result.Element(webNS + "Description").Value,
.Url = result.Element(webNS + "Url").Value})
End With
Next
resultListBox.ItemsSource = myWebInfo
End Sub
Else
flag = True
resultListBox.SetValue(ListBox.ItemTemplateProperty, Resources("ImageListBoxTemplate"))
Dim myUri = String.Format("http://api.search.live.net/xml.aspx?Appid={0}&query={1}&sources=image&web.count=20", AppID, TextBox1.Text)
Dim mmsNS As XNamespace = "http://schemas.microsoft.com/LiveSearch/2008/04/XML/multimedia"
Dim myWebClient As New WebClient
myWebClient.DownloadStringAsync(New Uri(myUri, UriKind.Absolute))
AddHandler myWebClient.DownloadStringCompleted, Sub(resultSender As Object, resultArgs As DownloadStringCompletedEventArgs)
Dim xmldoc As XElement = XElement.Parse(resultArgs.Result)
Dim myImageInfo As New List(Of ImageInfo)
For Each result In From c In xmldoc.Descendants(mmsNS + "ImageResult") Select c
With myImageInfo
.Add(New ImageInfo With {.Title = result.Element(mmsNS + "Title").Value,
.MediaUrl = result.Element(mmsNS + "MediaUrl").Value,
.Url = result.Element(mmsNS + "Url").Value})
End With
Next
resultListBox.ItemsSource = myImageInfo
End Sub
End If
End Sub
ListBox に表示された検索結果の項目が選択された時の処理
ブール型メンバ変数で条件分岐を行います。flag が False の時、つまり「Web 検索」にチェックが付いている場合は、ListBox(resultListBox) より選択された項目を WebInfo クラスにキャストし、「Url」プロパティの値を取得します。この値を引数にして、WebBrowserPage.xaml に遷移します。
flag が True の時、つまり「Image 検索」にチェックが付いている場合は、ListBox(resultListBox) より選択された項目を ImageInfo クラスにキャストし、「Url」プロパティの値を取得します。この値を引数にして、WebBrowserPage.xaml に遷移します。
Try~Catch~End Tryステートメントで例外処理を行っておいてください。この処理を怠るとエミュレータのBack(←)ボタンで戻った場合エラーが表示されます。
Private Sub resultListBox_SelectionChanged(sender As Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles resultListBox.SelectionChanged
Try
Dim myUrl As String = String.Empty
If flag = False Then
myUrl = DirectCast(resultListBox.SelectedItem, WebInfo).Url
Else
myUrl = DirectCast(resultListBox.SelectedItem, ImageInfo).Url
End If
NavigationService.Navigate(New Uri("/WebBrowserPage.xaml?uri=" & myUrl, UriKind.Relative))
Catch
Exit Sub
End Try
End Sub
End Class
次に、WebBrowserPage.xamlを展開して、WebBrowserPage.xaml.vbをダブルクリックして、リスト4のコードを記述します。
ロジックコードを記述する
リスト4 (WebBrowserPage.xaml.vb)
Option Strict On
Partial Public Class WebBrowserPage
Inherits PhoneApplicationPage
Public Sub New()
InitializeComponent()
End Sub
ページが読み込まれた時の処理
ここで、Mainpage..xamlから渡された文字データを受け取ります。文字データはNavigationContextのQueryStringにDictionary として提供されます。WebBrowser1.Navigateメソッドで引数として渡されたサイトに遷移します。WebBrowser内に指定したサイトが表示されます。
Private Sub WebBrowserPage_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
Dim param As IDictionary(Of String, String) = NavigationContext.QueryString
WebBrowser1.Navigate(New Uri(param("uri"), UriKind.Absolute))
End Sub
エミュレータのBack(←)ボタンを上書きする処理
NavigationService.GoBack()メソッドで、エントリが存在する場合は、"戻る" ナビゲーション履歴の最新のエントリに移動します
Protected Overrides Sub OnBackKeyPress(e As System.ComponentModel.CancelEventArgs)
NavigationService.GoBack()
MyBase.OnBackKeyPress(e)
End Sub
End Class
「Bing APIを使ってWeb検索とImage検索を実装する」サンプルプログラム
連載バックナンバー
Think ITメルマガ会員登録受付中
Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

