四文字熟語の意味をキャラクターが声で教えてくれるアプリを作る
次に、ソリューション・エクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト3のコードを記述します。
ロジックコードを記述する
リスト3 (MainWindow.xaml.vb)
Imports Windows.UI.Popups ‘ HeadItemクラス内に「頭」という文字列型のプロパティを定義します。 Public Class HeadItem Public Property 頭 As String End Class ‘ YonmpjiContentクラス内に文字列型の「四文字熟語」、「読み」、「意味」を定義します。 Public Class YonmojiContent Public Property 四文字熟語 As String Public Property 読み As String Public Property 意味 As String End Class Public NotInheritable Class MainPage Inherits Page ‘ キャラクタが読み上げる内容を格納するメンバー変数readingTextを宣言します。 Private readingText As String ‘ XML要素を表すXElementクラス型のメンバー変数xmldocを宣言します。 Private xmldoc As XElement Private myCount As Integer = 0 Private TotalCount As Integer = 0 ‘ 音声で読み上げさせるためのMediaElementクラス型のメンバー変数myMediaを宣言します。 Private myMedia As MediaElement
ページがアクティブになった時の処理
XElement.LoadメソッドでXML文書(yonmojijyukugo.xml)を読み込みます。
HeadItemクラス型の新しいリストである、myHeadItemオブジェクトを作成します。
DescenDantsメソッドで全ての子孫要素で、要素の要素から先頭の1文字分を抜き出して、重複しないの内容を変数resultに格納しながら、以下の処理を繰り返します。
メンバー変数myCountを1ずつ増加します。HeadItemクラスの「頭」プロパティに、要素から取り出した先頭の、重複しない1文字を指定して、AddメソッドでmyHeadItemオブジェクトに追加します。
headGridViewのItemsSourceプロパティにmyHeadItemオブジェクトを追加します。これで、要素の重複しない先頭の1文字が表示されます。
YonmojiContentクラスの新しいリストであるmyYonmojiContentオブジェクトを作成します。
Descendantsメソッドで全ての子孫要素の内容を、変数resultに格納しながら、以下の処理を繰り返します。
メンバー変数TotalCountを1ずつ増加します。
YonmojiContentクラスの、「四文字熟語」プロパティに要素の内容を、「読み」プロパティに要素の内容を、「意味」プロパティに要素の内容を指定して、AddメソッドでmyYomnojiContentオブジェクトに追加します。
GridView1のItemsSourceにmyYonmojiContentオブジェクトを追加します。
Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs) xmldoc = XElement.Load("yonmojijyukugo.xml") Dim myHeadItem As New List(Of HeadItem) For Each result In From c In xmldoc.Descendants("熟語") Select c.Element("読み").Value.Substring(0, 1) Distinct myCount += 1 myHeadItem.Add(New HeadItem With {.頭 = result}) Next headGridView.ItemsSource = myHeadItem Dim myYonmojiContent As New List(Of YonmojiContent) For Each result In From c In xmldoc.Descendants("熟語") Select c TotalCount += 1 myYonmojiContent.Add(New YonmojiContent With {.四文字熟語 = result.Element("四文字熟語").Value, .読み = result.Element("読み").Value, .意味 = result.Element("意味").Value}) Next GridView1.ItemsSource = myYonmojiContent End Sub
50音が選択された時の処理
メンバー変数myCountを0で初期化します。
変数headMojiにheadGridViewから選択された項目を、HeadItemクラスにキャストして、その「頭」プロパティを取得します。
YomnojiContentの新しいリストであるmyYonmojiContentオブジェクトを作成します。
Descendantsメソッドで全ての子孫要素の子要素の値が、変数headMojiで始まっている(StartsWith)要素の内容を、変数resultに格納しながら以下の処理を繰り返します。
メンバー変数myCountを1ずつ増加します。YonmojiContentクラスの、「四文字熟語」プロパティに要素の内容を、「読み」プロパティに要素の内容を、「意味」プロパティに要素の内容を指定して、AddメソッドでmyYomnojiContentオブジェクトに追加します。
mainGridViewのItemsSourceプロパティにmyYonmojiContentオブジェクトを追加します。これで、50音から選択した文字で始まる四文字熟語が全て表示されます。その四文字熟語は何個あるかを、countTextBlockにmyCountメンバー変数の格納している値と、文字列「登録数」とを連結して表示します。
Private Sub headGridView_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles headGridView.SelectionChanged Try myCount = 0 Dim headMoji = DirectCast(headGridView.SelectedItem, HeadItem).頭 Dim myYonmojiContent As New List(Of YonmojiContent) For Each result In From c In xmldoc.Descendants("熟語") Where c.Element("読み").Value.StartsWith(headMoji) Select c myCount += 1 myYonmojiContent.Add(New YonmojiContent With {.四文字熟語 = result.Element("四文字熟語").Value, .読み = result.Element("読み").Value, .意味 = result.Element("意味").Value}) Next mainGridView.ItemsSource = myYonmojiContent countTextBlock.Text = "【登録数】=" & myCount.ToString Catch Exit Sub End Try End Sub
検索の際に[実行]アイコンがタップされた時の処理
変数noを0で初期化します。
検索対象文字が未入力の場合は、警告メッセージを出して処理を抜けます。それ以外の場合は以下の処理を行います。
Descendantsメソッドで全ての子孫要素を選択したクエリを定義します。
そのクエリ内の要素の値を変数resultに格納しながら、以下の処理を行います。
もし、要素の値が、yomiWatermarkTextBlockに入力された値と同じであれば、GridViewの選択されたインデックスに1ずつ増加する変数noの値を指定し、ScrollIntoViewメソッドで、その位置までスクロールします。指定した四文字熟語が見つかれば、その位置までスクロールして選択状態にしてくれるということです。
もし、1ずつ増加する変数noの値が要素の個数と同じか、それより大きかった場合は、「該当する熟語がありません。」とメッセージを出して処理を抜けます。
Private Async Sub okButton_Click(sender As Object, e As RoutedEventArgs) Handles okButton.Click Dim no As Integer = 0 If yomiWatermarkTextBox.Text = String.Empty Then Dim message As New MessageDialog("読みを入力してください。") Await message.ShowAsync yomiWatermarkTextBox.Focus(Windows.UI.Xaml.FocusState.Pointer) Exit Sub Else Dim query = From c In xmldoc.Descendants("熟語") Select c '.Element("読み").Value.Equals(yomiWatermarkTextBox.Text) Select c For Each result In query If result.Element("読み").Value.Equals(yomiWatermarkTextBox.Text) Then GridView1.SelectedIndex = no GridView1.ScrollIntoView(GridView1.SelectedItem) Exit For End If If no >= query.Count - 1 Then Dim message As New MessageDialog("該当する熟語がありません。") Await message.ShowAsync no = 0 End If no += 1 Next End If End Sub
画面上でマウスの右をタップした時の処理
画面上に表示させていた、四文字熟語の個数を消去します。
Private Sub MainPage_RightTapped(sender As Object, e As RightTappedRoutedEventArgs) Handles Me.RightTapped countTextBlock.Text = String.Empty End Sub
50音から選択された四文字熟語を選択した際の処理
mainGridViewを引数にYomiAndMeanメソッドを実行します。
Private Sub mainGridView_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles mainGridView.SelectionChanged YomiAndMean(mainGridView) End Sub
「読み」と「意味」をキャラクタが音声で喋る処理
メンバー変数myMediaをMediaElement1で初期化しておきます。
音声機能へのアクセスを提供する、新しいSpeechSynthesizerのインスタンス、synthオブジェクトを作成します。
SynthesizeTextToStreamAsyncメソッドで、指定した文字列から、音声出力を非同期に生成します。
SetSourceメソッドで、指定されたストリームおよびMIME型を使用してSourceプロパティを設定します。Playメソッドで音声を再生します。
音声にどんな言語で、どのような声で喋らすかは、SpeechSynthesizerのVoiceプロパティで参照できます。下記のURLを参照してください。
> SpeechSynthesizer.Voice | voice property
上記URLを見るとJapanese JA は性別が「Female」で、名前は「Haruka」という女性が読み上げるようです。
非同期処理で行われるため、メソッドの先頭にAsyncを追加します。
Private Async Function syokoVoice() As Task myMedia = Me.MediaElement1 Dim synth = New Windows.Media.SpeechSynthesis.SpeechSynthesizer Dim stream = Await synth.SynthesizeTextToStreamAsync(readingText) myMedia.SetSource(stream, stream.ContentType) myMedia.Play() End Function
検索結果から表示された四文字熟語が選択された時の処理
GridView1を引数にYomiAndMeanメソッドを実行します。
Private Sub GridView1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles GridView1.SelectionChanged YomiAndMean(GridView1) End Sub
各GridViewの四文字熟語が選択された時に実行される処理
変数yomiにmyGridViewから選択された項目を、YonmojiContentクラスにキャストして、その「読み」プロパティの値を取得します。変数meanにmyGridViewから選択された項目を、YonmojiContentクラスにキャストして、その「意味」プロパティの値を取得します。
メンバー変数readingTextに変数yomiとmeanを指定して、「読み」と「意味」を読み上げるsykoVoiceタスクを実行します。
ProgressRing1を稼働させます。
非同期処理で行われるため、メソッドの先頭にAsyncを追加します。
Private Async Sub YomiAndMean(myGridView As GridView) Try Dim yomi = DirectCast(myGridView.SelectedItem, YonmojiContent).読み Dim mean = DirectCast(myGridView.SelectedItem, YonmojiContent).意味 readingText = yomi & "。意味は、" & mean & "です。" ProgressRing1.IsEnabled = True ProgressRing1.IsActive = True Await syokoVoice() Catch Exit Sub End Try End Sub
AppBar1が閉じられた時の処理
検索結果で選択されていたGridView1の選択を解除します。
Private Sub AppBar1_Closed(sender As Object, e As Object) Handles AppBar1.Closed GridView1.SelectedIndex = -1 End Sub
キャラクタが「読み」と「意味」を読み終えた時の処理
ProgressRing1を非稼働状態にします。
Private Sub MediaElement1_MediaEnded(sender As Object, e As RoutedEventArgs) Handles MediaElement1.MediaEnded ProgressRing1.IsEnabled = False ProgressRing1.IsActive = False End Sub End Class
今回で10回続いた連載も最終回です。お付き合いのほどありがとうございました。いかがだったでしょうか。皆様のWindows ストア・アプリ作成のアイデアのヒントにでもなれば、筆者としては嬉しい限りです。
では、またお会いする日まで…。
薬師寺国安
四文字熟語の意味をキャラクターが声で教えてくれるアプリ
『Windows 8.1+Visual Studio 2013によるWindows ストア・アプリ開発実例集』 第11回のサンプルプログラムです。