連載 :
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」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。