楽天の商品カテゴリから商品を検索できるプログラムを作る

2013年8月21日(水)
薬師寺 国安

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

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

リスト4 (MainWindow.xaml.vb)

Option Strict On

最新のHTTPアプリケーション用のプログラミングインターフェイスを提供するクラスの含まれる、System.Net.Http名前空間をインポートします。

Imports System.Net.Http

Imports Windows.UI.Popups

genreIdInfoクラス内に文字列型の「title」プロパティを定義しておきます。

Public Class genreIdInfo
  Public Property title As String
End Class
Public NotInheritable Class MainPage
  Inherits Page
  Dim sendData As String

XMLの要素を表すXElementクラス型のメンバ変数xmldocを宣言します。

 Dim xmldoc As XElement

 Dim selectGenreID As String

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

XElement.LoadメソッドでXML文書(RakutenGenreId.xml)を読み込みます。
genreIdInfoクラス型の新しいリストである、titleListオブジェクトを作成します。
Descendantsメソッドで全ての子孫要素に対して、その内容を変数resultに格納しながら、以下の処理を行います。
genreIdInfoクラスのtitleプロパティに要素の属性”title”の値を指定し、AddメソッドでtitleListオブジェクトに追加していきます。
GridViewのItemsSourceプロパティにtitleList1オブジェクトを指定します。ジャンルの一覧が表示されます。

  Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
    xmldoc = XElement.Load("RakutenGenreId.xml")
    Dim titleList As New List(Of genreIdInfo)
    For Each result In From c In xmldoc.Descendants("genreId") Select c
      titleList.Add(New genreIdInfo With {.title = result.Attribute("title").Value})
    Next
    GridView1.ItemsSource = titleList
  End Sub

ジャンルの一覧から任意のジャンルを選択した時の処理

マウスの右クリックで表示されるバーに配置されているsearchTextBoxのReadOnlyプロパティにFalseを指定して、入力可能な状態にし、フォーカスを持たせます。
「Yes」ボタンの使用を可能にします。

メンバ変数selectGenrdIDに、GridViewの選択された項目のインデックスに対応する要素の値を格納します。
「101240(CD,DVD,楽器のジャンルを選択した場合)」のよう数値文字列が格納されます。

  Private Sub GridView1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles GridView1.SelectionChanged
    searchTextBox.IsReadOnly = False
    searchTextBox.Text = String.Empty
    searchTextBox.Focus(Windows.UI.Xaml.FocusState.Pointer)
    okButton.IsEnabled = True
    selectGenreID = xmldoc.Descendants("genreId")(GridView1.SelectedIndex).Value
  End Sub

マウスの右クリックで表示されるバーに配置された「Yes」ボタンがタップされた時の処理

検索項目がきちんと入力されていた場合の処理です。

myFrameを表示状態にし、searchTextBoxの編集を不可とし、「Yes」ボタンの使用を不可とします。

メンバ変数sendDataにsearchTextBoxに入力された値と、メンバ変数selectGenreIDが格納している値を、カンマで区切って格納します。バーであるAppBar1を非表示にし、Navigateメソッドで、sendDataを引数にして、SearchResultPageに遷移します。

検索項目が入力されていなかった場合は、警告メッセージを表示し、searchTextBoxの入力を可能に、「Yes」ボタンの使用を可能にして処理を抜けます。

  Private Async Sub okButton_Click(sender As Object, e As RoutedEventArgs) Handles okButton.Click
    If searchTextBox.Text<>String.Empty Then
    myFrame.Visibility = Windows.UI.Xaml.Visibility.Visible
    searchTextBox.IsReadOnly = True
    okButton.IsEnabled = False
    sendData = searchTextBox.Text& "," &selectGenreID
    AppBar1.Visibility = Windows.UI.Xaml.Visibility.Collapsed
    myFrame.Navigate(GetType(SearchResultPage), sendData)
  Else
    Dim message As New MessageDialog("検索項目を入力してください。")
    Await message.ShowAsync
    searchTextBox.IsReadOnly = False
    okButton.IsEnabled = True
    sendData = String.Empty
    Exit Sub
  End If
End Sub

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

ジャンルが選択されている場合は、searchTextBoxの入力を可能に、「Yes」ボタンの使用を可能にします。それ以外は、searchTextBoxの入力は不可、「Yes」ボタンの使用も不可としておきます。

Appbarを表示状態にし、myFrameを非表示にします。ジャンルの一覧が表示されたページが現れます。

  Private Sub backButton_Click(sender As Object, e As RoutedEventArgs) Handles backButton.Click
    If GridView1.SelectedIndex >= 0 Then
      searchTextBox.IsReadOnly = False
      okButton.IsEnabled = True
    Else
      searchTextBox.IsReadOnly = True
      okButton.IsEnabled = False
    End If
    AppBar1.Visibility = Windows.UI.Xaml.Visibility.Visible
    myFrame.Visibility = Windows.UI.Xaml.Visibility.Collapsed
  End Sub
End Class

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

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

リスト5 (SearchResultPage.xaml.vb)

Public NotInheritable Class WebBrowserPage
  Inherits Page
Option Strict On

Imports System.Net.Http
Imports Windows.UI.Popups

ProductInfoクラス内に文字列型の「画像」、「商品名」、「価格」、「サイト」というプロパティを定義しておきます。

Public Class ProductInfo
  Public Property 画像 As String
  Public Property 商品名 As String
  Public Property 価格 As String
  Public Property サイト As String
End Class
Public NotInheritable Class SearchResultPage
  Inherits Page

文字列型定数メンバ変数AppIDを宣言し、Yahooより取得したApplicationIdで初期化しておきます。

  ConstAppID As String = "Yahooより取得したApplicationId"

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

MainPage.xamlより渡された値は、e.Parameterで取得できます。これはObject型であるため、DirectCastで文字列型にキャストして、変数myGetDataに格納しておきます。

変数myGetDataに格納されている値は、カンマで区切られているため、配列変数searchItemを宣言し、Split関数を使って、カンマで区切られた、それぞれの値を取得して、格納しておきます。

変数mySortにエスケープ表現された+itemPrice(価格順でソート)といった文字列を格納しておきます。

変数myUriに「楽天商品検索API2(Version:2012-07-23)」で提供される、リクエストURLを格納します。

applicationIdには定数メンバ変数AppIDの値を、keywordには、配列変数searchItem(0)の値をエスケープ表現した値、これは検索ボックスに入力した値、を指定します。sortには変数mySortの値を、genreIdにはsearchItem(1)の値、これはリスト1のXML文書内の、要素の値、を指定します。formatにはxmlをしていします。jsonの指定もできます。
新しいHttpClientのインスタンスmyHttpClient オブジェクトを作成します。GetStringAsyncメソッドで、変数myUriから返される結果XMLを取得して変数myResponseに格納します。

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

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

ProductInfoクラスの画像プロパティに要素の値を、商品名プロパティに、要素の値を、価格プロパティに、三桁区切りで「円」を連結した要素の値を、サイトプロパティに、要素の値を指定して、AddメソッドでmyProductInfoオブジェクトに追加していきます。出力パラメータについては、下記のURLを参照してください。
→ 楽天商品検索API

GridViewのItemsSourceプロパティにmyProductInfoオブジェクトを指定します。これで、検索結果の情報がタイルで一覧表示されます。

  Protected Overrides AsyncSub OnNavigatedTo(e As Navigation.NavigationEventArgs)
    Dim myGetData As String = DirectCast(e.Parameter, String)
    Dim searchItem() As String = myGetData.Split(CChar(","))
    Dim mySort As String = Uri.EscapeDataString("+itemPrice")
    Dim myUri As String = String.Format("https://app.rakuten.co.jp/services/api/IchibaItem/Search/20120723?applicationId={0}&keyword={1}&sort={2}&genreId={3}&format=xml", AppID, Uri.EscapeDataString(searchItem(0)), mySort, searchItem(1))
    Dim myHttpClient As New HttpClient
    Dim myResponse = Await myHttpClient.GetStringAsync(New Uri(myUri, UriKind.Absolute))
    Dim xmldoc As XElement = XElement.Parse(myResponse)
    
    Dim myProductInfo As New List(Of ProductInfo)
    For Each result In From c In xmldoc.Descendants("Item") Select c
      With myProductInfo
        .Add(New ProductInfo With {.画像 = result.Element("mediumImageUrls").Value,
                                   .商品名 = result.Element("itemName").Value,
                                   .価格 = String.Format("{0:n0}円", Integer.Parse(result.Element("itemPrice").Value)),
                                   .サイト = result.Element("itemUrl").Value})
      End With
  Next
  GridView1.ItemsSource = myProductInfo
End Sub

任意のタイルを選択した時の処理

myFrameを表示状態にします。
変数myUriにGridViewより選択された項目を、DirectCastでProductInfoクラスにキャストして、そのサイトプロパティの値を取得して格納します。
Navigateメソッドで、変数myUriを引数に、WebBrowserPageに遷移します。

  Private Async Sub GridView1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles GridView1.SelectionChanged
    myFrame.Visibility = Windows.UI.Xaml.Visibility.Visible
    Dim myUri = DirectCast(GridView1.SelectedItem, ProductInfo).サイト
    myFrame.Navigate(GetType(WebBrowserPage), myUri)
  End Sub
End Class

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

myFrameを非表示にします。タイルの一覧が表示されているページが表示されます。

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

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

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

リスト6 (WebBrowserPage.xaml.vb)

Option Strict On
Public NotInheritable Class WebBrowserPage
  Inherits Page

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

SearchResultPage.xamlより渡された値は、e.Parameterで取得できます。これはObject型であるため、DirectCastで文字列にキャストして、変数myUriに格納します。

WebBrowserのSourceプロパティに、変数myUriで初期化された新しいUriを指定します。ブラウザ内に指定したページが表示されます。

  Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
    Dim myUri = 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フォルダに追加しておきます。
詳細については、「自分の現在位置を取得して表示するサンプルプログラム」の記事を参照してください。

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

  • 楽天の商品検索APIを使って、商品のジャンル別検索を行うアプリサンプル

薬師寺国安事務所

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

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