サーバー上の画像取得とRSSのデータを表示する

2011年8月5日(金)
PROJECT KySS

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

リスト6 (MainPage.xaml.vb)

Option Strict On

LINQ to XMLを利用するためSystem.Xml.Linq名前空間をインポートします。
Imports System.Xml.Linq
Partial Public Class MainPage
  Inherits PhoneApplicationPage

~コード略~

ページが読み込まれた時の処理

ReadXmldocクラスの新しいインスタンスmyReadXmldoc変数を宣言します。
文字列型の新しいリストである、titleList変数を宣言します。
ReadXmldocクラスのインスタンスmyReadXmldocでCodeRecipeDoc関数を呼び出します。Descendantsメソッドで取得した<タイトル>要素のコレクションに対して、各要素を変数 result に格納しながら以下の処理を実行します。
リストであるtitleListオブジェクトに、<タイトル>要素の内容をAddメソッドで追加していきます。ListBoxのItemsSourceプロパティにtitleListオブジェクトを指定します。これで、分類の一覧が表示されます。
  Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    Dim myReadXmldoc As New ReadXmldoc
    Dim titleList As New List(Of String)
 
    For Each result In From c In myReadXmldoc.CodeRecipeDoc.Descendants("タイトル") Select c
      titleList.Add(result.Value)
    Next
    ListBox1.ItemsSource = titleList
  End Sub

ListBoxから項目が選択された時の処理

ListBoxより選択された項目のインデックスを文字列に変換して、変数myIndexに格納しておきます。
NavigationService.Navigateメソッドで、CodeRecipeIndex.xamlに遷移します。その際、Indexというキーワードに変数myIndexの値を引数として持たせています
  Private Sub ListBox1_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles ListBox1.SelectionChanged
    Dim myIndex As String = ListBox1.SelectedIndex.ToString
    NavigationService.Navigate(New Uri("/CodeRecipeIndex.xaml?Index=" & myIndex, UriKind.Relative))
  End Sub
End Class

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

リスト7 (CodeRecipeIndex.xaml.vb)

Option Strict On
Imports System.Xml.Linq

Partial Public Class CodeRecipeIndex
  Inherits PhoneApplicationPage
~コード略~

ReadXmldocクラスの新しいインスタンスmyReadXmldocをメンバ変数として宣言します。
  Dim myReadXmldoc As New ReadXmldoc
文字列型の新しいリストであるuriListをメンバ変数として宣言します。
  Dim uriList As New List(Of String)
数値型のメンバ変数Indexを宣言します。このIndexには、エミュレーターのBack(←)ボタンがクリックされて、該当ページに遷移する際に、MainPage.xamlの分類で選択された項目のインデックス番号が格納され、各遷移ページに渡されます。
  Dim Index As Integer = 0

画面の遷移で移動した時に最初に呼ばれるイベント

ここで、MainPage.xamlから渡された文字データを受け取ります。文字データはNavigationContextのQueryStringにDictionary として提供されます。
ContainsKeyメソッドで、指定したキー(ここでは、Index)が Dictionary に格納されているかどうかを判断し、格納されている場合は、数値に変換して、myParam(“Index”)の値を変数Indexに格納します。
新しい、WebClientのインスタンス、myWebClientを生成します。
ReadXmldocクラスのインスタンスmyReadXmldocでCodeRecipeDoc関数を呼び出します。Descendantsメソッドで取得した、変数Indexに対応する<タイトル>要素の、”uri”属性の値を取得して、変数myUriに格納します。
OpenReadAsyncメソッドで、指定したURIを開きます。絶対URIで指定します。OpenReadAsyncメソッドは、指定したリソースに対する読み取り可能なストリームを開くメソッドです。
AddHandlerメソッドで、OpenReadCompletedイベントハンドラを追加します。OpenReadCompletedイベントは、非同期のリソース読み取り操作の完了時に発生します。
OpenReadCompletedイベント内では以下の処理を行います。
リソースの読み取りに失敗した場合は、エラーメッセージボックスを表示させます。
リソースの読み取りに成功した場合は、XElement.Loadメソッドでリソース(resultArgs.Result)を読み込みます。文字列型の新しいリストであるtitleListを生成します。Descendantsメソッドで取得した<item>要素のコレクションに対して、各要素を変数 result に格納しながら以下の処理を実行します。
titleListオブジェクトに<title>要素の内容を追加し、uriListオブジェクトに<link>要素の内容を追加していきます。ListBoxのItemsSourceプロパティにtitleListオブジェクトを指定します。目次が表示されます。
  Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs)
    Dim myParam As IDictionary(Of String, String) = Me.NavigationContext.QueryString
    If myParam.ContainsKey("Index") = True Then
      Index = Integer.Parse(myParam("Index"))
      Dim myWebClient As New WebClient
  
      AddHandler myWebClient.OpenReadCompleted, Sub(resultSender As Object, resultArgs As OpenReadCompletedEventArgs)
                                                If resultArgs.Error Is Nothing = False Then
                                                     MessageBox.Show("RSSファイル読み取りエラー")
                                                     Exit Sub
                                                Else
                                                     Dim doc As XElement = XElement.Load(resultArgs.Result)
                                                     Dim titleList As New List(Of String)
                                                     For Each result In From c In doc.Descendants("item") Select c
  
  titleList.Add(result.Element("title").Value)
  
  uriList.Add(result.Element("link").Value)
                                                     Next
  
                                                     ListBox1.ItemsSource = titleList
                                                 End If
                                              End Sub
      Dim myUri As String = myReadXmldoc.CodeRecipeDoc.Descendants("タイトル")(Index).Attribute("uri").Value
      myWebClient.OpenReadAsync(New Uri(myUri, UriKind.Absolute))
    End If
    MyBase.OnNavigatedTo(e)
  End Sub

エミュレーターのBack(←)ボタンのイベントを上書きする処理

エミュレーターの持っている本来のBack処理を、e.Cancel=Trueで無効とします。
NavigationService.NavigateメソッドでMainPage.xamlに遷移します。
Protected Overrides Subと入力すると、インテリセンス機能が働き、イベントの一覧が表示されますので、その中から選択してください。
  Protected Overrides Sub OnBackKeyPress(ByVal e As System.ComponentModel.CancelEventArgs)
    e.Cancel = True
    Me.NavigationService.Navigate(New Uri("/MainPage.xaml", UriKind.Relative))
    MyBase.OnBackKeyPress(e)
  End Sub

ListBoxから項目(目次)を選択した時の処理

ListBoxより選択された項目名を変数selectTitleに格納し、Replaceメソッドで[C#]という文字を[CSharp]という文字に置換します。#という文字が含まれていると、PageView.xamlに遷移した際エラーになるためです。
NavigationService.NavigateメソッドでPageView.xamlに遷移します。その際、TitleキーワードにselectTitle、UriキーワードにListBoxより選択されたインデックスに該当するuriList、そして、Indexキーワードにメンバ変数Indexの値を渡しています。IndexにはMainPage.xamlの分類で選択された項目のインデックス番号が格納されています。
  Private Sub ListBox1_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles ListBox1.SelectionChanged
    Dim selectTitle As String = ListBox1.SelectedItem.ToString
    selectTitle = selectTitle.Replace("[C#]", "[CSharp]")
    NavigationService.Navigate(New Uri("/PageView.xaml?Title=" & selectTitle & "&Uri=" & uriList(ListBox1.SelectedIndex) & "&Index=" & Index, UriKind.Relative))
  End Sub

エミュレーターの表示方向が変化する時に発生するイベント

エミュレーターが横向きになった時はListBoxのWidthの値を広くとります。
  Private Sub CodeRecipeIndex_OrientationChanged(sender As Object, e As Microsoft.Phone.Controls.OrientationChangedEventArgs) Handles MyBase.OrientationChanged
    ListBox1.Width = Me.ActualWidth
  End Sub
End Class

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

リスト8 (PageView.xaml.vb)

Option Strict On

Partial Public Class PageView
  Inherits PhoneApplicationPage
~コード略~
  Dim Index As Integer = 0

ページが読み込まれた時の処理

CodeRecipeIndex.xamlから渡された文字データを受け取ります。文字データはNavigationContextのQueryStringにDictionary として提供されます。myParam(“Title”)でTitleパラメータに渡された値を受け取り、変数myTitleに格納します。myParam(“Index”)でIndexに渡された値を、数値に変換してメンバ変数Indexに格納します。PageTitleという名前のTextBlockにmyTitle変数の値を表示します。CodeRecipeIndex.xamlから渡された目次が表示されます。myParam(“Uri”)でUriパラメータに渡された値を受け取り、変数myUriに格納します。WebBrowserのNavigateメソッドにmyUriの値を絶対URIで指定します。WebBrowser内にサイトが表示されます。
  Private Sub PageView_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    Dim myParam As IDictionary(Of String, String) = Me.NavigationContext.QueryString
 
    Dim myTitle As String = myParam("Title")
    Index = Integer.Parse(myParam("Index"))
    PageTitle.Text = myTitle
    Dim myUri As String = myParam("Uri")
    WebBrowser1.Navigate(New Uri(myUri, UriKind.Absolute))
  End Sub

エミュレーターのBack(←)ボタンのイベントを上書きする処理

エミュレーターの持っている本来のBack処理を、e.Cancel=Trueで無効とします。
NavigationService.NavigateメソッドでCodeRecipeIndex.xamlに遷移します。引数にメンバ変数Indexの値を渡しています。IndexにはMainPage.xamlの分類で選択された項目のインデックス番号が格納されています。
Protected Overrides Subと入力すると、インテリセンス機能が働き、イベントの一覧が表示されますので、その中から選択してください。
  Protected Overrides Sub OnBackKeyPress(ByVal e As System.ComponentModel.CancelEventArgs)
    Me.NavigationService.Navigate(New Uri("/CodeRecipeIndex.xaml?Index=" & Index, UriKind.Relative))
    e.Cancel = True
    MyBase.OnBackKeyPress(e)
  End Sub

エミュレーターの表示方向が変化する時に発生するイベント

エミュレーターが横向きになった時はWebBrowserのWidthの値を広くとります。
  Private Sub PageView_OrientationChanged(sender As Object, e As Microsoft.Phone.Controls.OrientationChangedEventArgs) Handles MyBase.OrientationChanged
  WebBrowser1.Width = Me.ActualWidth
  End Sub
End Class
  • 「サーバー上の画像取得とRSSのデータを表示する」サンプルプログラム_1

  • 「サーバー上の画像取得とRSSのデータを表示する」サンプルプログラム_2

四国のSOHO。薬師寺国安(VBプログラマ)と、薬師寺聖(デザイナ、エンジニア)によるコラボレーション・ユニット。1997年6月、Dynamic HTMLとDirectAnimationの普及を目的として結成。共同開発やユニット名義での執筆活動を行う。XMLおよび.NETに関する著書や連載多数。最新刊は「Silverlight実践プログラミング」両名とも、Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。http://www.PROJECTKySS.NET/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

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