青空文庫を検索して目的の作品を探すプログラムを作る

2013年5月17日(金)
薬師寺 国安

マウスの右ボタンクリックで、表示された著者名検索入力ボックスに、著者名を入力して「Yes」ボタンがクリックされた時の処理

著者名を格納しているmyWriterList内を変数iで反復処理を行います。
CountプロパティでmyWriterList内に格納されている著者名の個数を取得して、その個数分反復処理を行います、-1しているのは、myWriterList変数内に格納されている著者名のインデックスが0から始まるためです。

変数iに対応するmyWriterList内の著者名が、WatermarkTextBoxに入力された値と同じなら、GridViewの選択されたインデックスにiを指定し、ScrollIntoViewで、その著者名の位置までスクロールさせ、反復処理を抜けます。しかし、著者名が正しく入力されていた場合は、GridViewの著者名が選択されたことになりますので、即!作品のページに遷移してしまいます。

変数iがmyWriterListの最後まで達した場合は、該当する著者名が見つからなかったことになりますので、警告メッセージを発して、反復処理から抜けます。

  Private Async Sub okButton_Click(sender As Object, e As RoutedEventArgs) Handles okButton.Click
    Dim no As Integer = 0
    If WatermarkTextBox1.Text <>String.Empty Then
      Dim searcAuthor As String = WatermarkTextBox1.Text
      For i As Integer = 0 To myWriterList.Count - 1
        If myWriterList(i) = searcAuthor Then
          GridView1.SelectedIndex = i
          GridView1.ScrollIntoView(GridView1.SelectedItem)
          Exit For
        End If
        If i = myWriterList.Count - 1 Then
          Dim message As New MessageDialog("著者名が正しいかどうか確認してください。")
          Await message.ShowAsync
          WatermarkTextBox1.Focus(Windows.UI.Xaml.FocusState.Pointer)
          Exit For
        End If
      Next
    End If
  End Sub

GridViewに表示されている著者名が選択された時の処理

PCの解像度が1024×768であった場合は、Frameの幅を1000に、高さを720に設定します。

Frameを表示状態にし、マウスの右クリックで表示されるバーであるmyApp1を非表示にします。
メンバ変数myAuthorにGridViewの選択されたインデックスに該当するmyWriterList内の著者名を格納します。この著者名を引数にしてWorkShowPageに遷移します。

  Private Sub GridView1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles GridView1.SelectionChanged
    Dim myWidth = CInt(Window.Current.CoreWindow.Bounds.Width)
    Dim myHeight = CInt(Window.Current.CoreWindow.Bounds.Height)
    If myWidth = 1024 AndAlsomyHeight = 768 Then
      myFrame.Width = 1000
      myFrame.Height = 720
    End If
    myFrame.Visibility = Windows.UI.Xaml.Visibility.Visible
    AppBar1.Visibility = Windows.UI.Xaml.Visibility.Collapsed
    myAuthor = myWriterList(GridView1.SelectedIndex)
    myFrame.Navigate(GetType(WorkShowPage), myAuthor)
  End Sub

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

モジュールで宣言しておいたPageFlagがTrueなら、WorkShowPageに遷移し、そうでないなら、GridViewを表示し、Frameを非表示に、Appbar1を表示状態にします。つまり、著者名一覧が表示されます。

  Private Sub backButton_Click(sender As Object, e As RoutedEventArgs) Handles backButton.Click
    If PageFlag = True Then
      myFrame.Navigate(GetType(WorkShowPage), myAuthor)
    Else
      GridView1.Visibility = Windows.UI.Xaml.Visibility.Visible
      myFrame.Visibility = Windows.UI.Xaml.Visibility.Collapsed
      AppBar1.Visibility = Windows.UI.Xaml.Visibility.Visible
    End If
  End Sub
End Class

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

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

リスト6 (WorkShowPage.xaml.vb)

Option Strict On

Imports Windows.UI.Popups

WorkInfoクラス内に文字列型の「作品名」と「URL」プロパティを宣言しておきます。

Public Class WorkInfo
  Property 作品名 As String
  Property URL As String
End Class
Public NotInheritable Class WorkShowPage
  Inherits Page

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

  Dim xmldoc As XElement

文字列型の新しいリストである、メンバ変数myWorkListオブジェクトを作成します。

  Dim workList As New List(Of String)

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

PageFlagをFalseで初期化します。

PCの解像度を取得し、横と縦のサイズをmyWidthとmyHeight変数に格納します。

解像度が1024×768の場合は、GridViewの幅を1000にFrameの幅を1000、高さを720に設定します。何も設定しないでおくと、1024×768の解像度では表示される内容が切れて表示されますので、注意が必要です。

MainPageから送られた値はe.Parameterで取得できます。これはObject型であるため、DirectCastで文字列に変換して、変数muAuthorに格納しておきます。

XElement.LoadメソッドでXML文書(Novel.xml)を読み込みます。
WorkInfoクラスの新しいリストである、myWorkInfoオブジェクトを作成します。

Descendantsメソッドで、全ての子孫要素に対して、その子要素の内容が、変数myAuthorと同じであるの要素の内容をresultに格納しながら、以下の処理を行います。

WorkInfoクラスの「作品名」プロパティに要素の値を、URLに要素の値を指定して、AddメソッドでリストであるmyWorkInfoに追加していきます。また、workListオブジェクトにもAddメソッドで要素の内容を追加していきます。

GridViewのItemsSourceプロパティにmyWorkInfoオブジェクトを指定します。これで、作品名の一覧が表示されます。

  Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
    PageFlag = False
    Dim myWidth = CInt(Window.Current.CoreWindow.Bounds.Width)
    Dim myHeight = CInt(Window.Current.CoreWindow.Bounds.Height)
    If myWidth = 1024 AndAlsomyHeight = 768 Then
      GridView1.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Left
      GridView1.Width = 1000
      myFrame.Width = 1000
      myFrame.Height = 720
    Else
 
    End If
    Dim myAuthor = DirectCast(e.Parameter, String)
    xmldoc = XElement.Load("Novel.xml")
    Dim myWorkInfo As New List(Of WorkInfo)

For Each result In From c In xmldoc.Descendants("Novel") Where c.Element("著者名").Value.Equals(myAuthor) Select c myWorkInfo.Add(New WorkInfo With {.作品名 = result.Element("作品名").Value, .URL = result.Element("URL").Value}) workList.Add(result.Element("作品名").Value) Next GridView1.ItemsSource = myWorkInfo End Sub

GridViewに表示されている作品名が選択された時の処理

PCの解像度が1024×768であった場合は、Frameの幅を1000に、高さを720に設定します。

変数myUrlにGridViewから選択された項目を、WorkInfoクラスにキャストして、そのURLプロパティの値を取得して格納しま す。このURLを引数にしてWebBrowserPageに遷移します。

  Private Sub GridView1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles GridView1.SelectionChanged
    Dim myWidth = CInt(Window.Current.CoreWindow.Bounds.Width)
    Dim myHeight = CInt(Window.Current.CoreWindow.Bounds.Height)
    If myWidth = 1024 AndAlsomyHeight = 768 Then
      myFrame.Width = 1000
      myFrame.Height = 720
    End If
    Dim myURL = DirectCast(GridView1.SelectedItem, WorkInfo).URL
    myFrame.Navigate(GetType(WebBrowserPage), myURL)
  End Sub

マウスの右ボタンクリックで表示された作品名検索入力ボックスに、作品名を入力して「Yes」ボタンがクリックされた時の処理

作品名を格納しているworkList内を変数iで反復処理を行います。
CountプロパティでworkList内に格納されている作品名の個数を取得して、その個数分反復処理を行います。-1しているのは、workList変数内に格納されている作品名のインデックスが0から始まるためです。

変数iに対応するworkList内の作品名が、WatermarkTextBoxに入力された値と同じなら、GridViewの選択されたインデックスにiを指定し、ScrollIntoViewでその著者名の位置までスクロールさせ、反復処理を抜けます。しかし、著者名が正しく入力されていた場合は、GridViewの著者名が選択されたことになりますので、即!作品がWebViewに表示されるページに遷移してしまいます。

変数iがworkListの最後まで達した場合は、該当する作品名が見つからなかったことになりますので、警告メッセージを発して、フォーカスをWatermarkTextBoxに移し、反復処理から抜けます。

  Private Async Sub okButton_Click(sender As Object, e As RoutedEventArgs) Handles okButton.Click
    Dim no As Integer = 0
    If WatermarkTextBox1.Text <>String.Empty Then
      Dim searchWork As String = WatermarkTextBox1.Text
      For i As Integer = 0 To workList.Count - 1
        If workList(i) = searchWork Then
          GridView1.SelectedIndex = i
          GridView1.ScrollIntoView(GridView1.SelectedItem)
          Exit For
        End If
        If i = workList.Count - 1 Then
          Dim message As New MessageDialog("作品名が正しいかどうか確認してください。")
          Await message.ShowAsync
          WatermarkTextBox1.Focus(Windows.UI.Xaml.FocusState.Pointer)
          Exit For
        End If
      Next
    End If
  End Sub
End Class

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

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

リスト7 (WebBrowserPage.xaml.vb)

Option Strict On
  Public NotInheritable Class WebBrowserPage
Inherits Page

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

PageFlagをTrueで初期化します。

PCの解像度が1024×768の場合は、WebViewの幅を1024、高さを720に設定します。

WorkShowPageから送られた値はe.Parameterで取得できます。これはObject型であるため、DirectCastで文字列に変換して、変数myUrlに格納します。WebViewのNavigateメソッドに、myUrlで初期化された新しいUriを指定します。これで、WebView内に作品の内容が表示されます。

  Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
    PageFlag = True
    Dim myWidth = CInt(Window.Current.CoreWindow.Bounds.Width)
    Dim myHeight = CInt(Window.Current.CoreWindow.Bounds.Height)
    If myWidth = 1024 AndAlsomyHeight = 768 Then
      WebView1.Width = 1024
      WebView1.Height = 720
    End If
    Dim myUrl = DirectCast(e.Parameter, String)
    WebView1.Navigate(New Uri(myUrl, UriKind.Absolute))
  End Sub
End Class

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

このサンプルを応用したアプリを下記のURLで公開しています。
→ 青空文庫検索(Windowsストア)

筆者からのお知らせ

筆者はWindowsストアでアプリを公開しています。チャームの検索からWindowsストアを選択して、検索欄に、kuniyasuまたはYakushijiKuniyasuと入力すると、公開されているアプリの一覧が表示されます。上記はどちらも私のアカウントですので、興味のある方は是非ダウンロードして使ってみてください。

  • 青空文庫を検索して目的の作品を探すプログラム

薬師寺国安事務所

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

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