パノラマページを作成する(後編)

2011年7月22日(金)
PROJECT KySS

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

リスト2 曲を再生する処理 (seiSong.xaml.vb)

001Option Strict On
002Imports System.Xml.Linq
003 
004タイマーの機能を提供するクラスの含まれる、System.Windows.Threading名前空間をインポートしておきます。
005Imports System.Windows.Threading
006 
007画像を表示するのに必要な機能の含まれる、System.Windows.Media.Imaging名前空間をインポートしておきます。
008Imports System.Windows.Media.Imaging
009Partial Public Class seiSong
010  Inherits PhoneApplicationPage
011 
012~コード略~
013 
014タイマーを表すDispatcherTimerクラスのインスタンスdtオブジェクトを、メンバ変数として宣言します。
015  Dim dt As New DispatcherTimer
016  Dim no As Boolean = False
017 
018ReadXmldocクラスのインスタンスmyReadXmldocオブジェクトをメンバ変数として宣言します。
019  Dim myReadXmldoc As New ReadXmldoc
020 
021■画面の遷移で移動した時に最初に呼ばれるイベント
022ここで、MainPage.xamlから渡された文字データを受け取ります。文字データはNavigationContextのQueryStringにDictionary として提供されます。送信時のキーワード(この場合Index)を基に渡された文字列情報を、myParam(“Index”)として取得します。
023myParam(“Index”)の値を数値に変換して、変数Indexに格納します。
024ReadXmldocクラスのインスタンスmyReadXmldocでseiSong関数を呼び出します。Descendantsメソッドで、変数Indexに該当する<Music>要素の値を取得し、変数myTitleに格納します。
025同じく、変数Indexに該当する<Music>要素の属性”Uri”の値を取得し、変数mySongに格納します。
026x:NameがPageTitleというTextBlockにmyTitleの値を表示します。曲名が表示されます。
027MediaElementのSourceプロパティに絶対URIとして、変数mySongの値を指定します。前編のリスト1の、SeiMusic.xmlの”Uri”属性に記述されたアドレスにアクセスします。
028Volumeプロパティの値に1を指定します。Volumeプロパティには0~1の値を指定できます。規定値は0.5です。
029変数Indexに該当する<Music>要素の属性”Image”値を取得し、変数imageNameに格納します。
030ImageのSourceプロパティに、画像を置いてあるImageフォルダーを連結したimageNameの値を相対URIで指定します。
031  Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs)
032    Dim myParam As IDictionary(Of String, String) = NavigationContext.QueryString
033    Dim Index As Integer = Integer.Parse(myParam("Index"))
034    Dim myTitle As String = myReadXmldoc.seiSong.Descendants("Music")(Index).Value
035    Dim mySong As String = myReadXmldoc.seiSong.Descendants("Music")(Index).Attribute("Uri").Value
036    PageTitle.Text = myTitle
037    MediaElement1.Source = New Uri(mySong, UriKind.Absolute)
038    MediaElement1.Volume = 1
039    Dim imageName As String = myReadXmldoc.seiSong.Descendants("Music")(Index).Attribute("Image").Value
040    Image1.Source = New BitmapImage(New Uri("Image/" & imageName, UriKind.Relative))
041    MyBase.OnNavigatedTo(e)
042  End Sub
043 
044■メディアストリームが検証されて開かれ、ファイル ヘッダーが読み取られると発生する処理
045AddHandlerメソッドで、タイマー間隔が経過すると発生するTickイベントに、イベントハンドラを追加します。イベントハンドラ内では下記の処理を行います。
046タイマーの経過に伴い、ProgressBar を進行させます。経過時間を示す MediaElement.Position.TotalSecondsを、MediaElement.NaturalDuration.TimeSpan.TotalSeconds で取得したメディア・ファイルの継続時間で除算することにより、メディア・ファイルに対する再生時間の比率を求め、ProgressBarのデフォルトのMaximumである100を乗算して、ProgressBar の値に設定します。これで、曲の再生と同期してプログレスバーが進行します。
047Startメソッドでタイマーを開始します。
048  Private Sub MediaElement1_MediaOpened(sender As Object, e As System.Windows.RoutedEventArgs) Handles MediaElement1.MediaOpened
049    AddHandler dt.Tick, Sub()
050                             ProgressBar1.Value = MediaElement1.Position.TotalSeconds / MediaElement1.NaturalDuration.TimeSpan.TotalSeconds * 100
051                        End Sub
052      dt.Start()
053  End Sub
054 
055■曲の再生が完了した時の処理
056[Pause]ボタンを使用不可とし、[Play]ボタンを使用可能にします。ブール型変数noにTrueを指定します。タイマーを中止します。
057  Private Sub MediaElement1_MediaEnded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles MediaElement1.MediaEnded
058    PauseButton.IsEnabled = False
059    PlayButton.IsEnabled = True
060    no = True
061    dt.Stop()
062  End Sub
063 
064■[Pause]ボタンがクリックされた時の処理
065曲の再生を休止し、[Play]ボタンを使用可能、[Pause]ボタンを使用不可とします。
066  Private Sub PauseButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles PauseButton.Click
067    MediaElement1.Pause()
068    PlayButton.IsEnabled = True
069    PauseButton.IsEnabled = False
070  End Sub
071 
072■[Playボタンがクリックされた時の処理
073ブール型変数noの値で条件分岐を行います。noの値がTrueの時、つまり、曲が最後まで再生し切った場合は、PositionプロパティにTimeSpan.Zeroと指定し、再生開始位置を0秒時点に戻します。ProgressBarの値を0で初期化し、タイマーを開始します。no変数にFalseを指定します。
074曲を再生し、[Play]ボタンを使用不可、[Pause]ボタンを使用可とします。
075  Private Sub PlayButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles PlayButton.Click
076    If no = True Then
077      MediaElement1.Position = TimeSpan.Zero
078      ProgressBar1.Value = 0
079      dt.Start()
080      no = False
081    End If
082    MediaElement1.Play()
083    PlayButton.IsEnabled = False
084    PauseButton.IsEnabled = True
085  End Sub
086 
087■[Topに戻る]ボタンがクリックされた時の処理
088タイマーを中止し、MainPage.xamlに遷移します。
089  Private Sub TopButton_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles TopButton.Click
090    dt.Stop()
091    Me.NavigationService.Navigate(New Uri("/MainPage.xaml", UriKind.Relative))
092  End Sub
093 
094■プログレスバーの上でマウスの左ボタンが押下された時の処理
095GetPosition メソッドで座標を取得し、ProgressBar の幅に対する比率を求め、メディアの継続時間に乗算して、クリックした位置に相当するメディアの秒数を計算します。TimeSpan.FromSeconds を用いて、これを再生開始位置として指定します。
096  Private Sub ProgressBar1_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles ProgressBar1.MouseLeftButtonDown
097    Dim myPoint As New Point
098    myPoint = e.GetPosition(ProgressBar1)
099    Dim mySecond As Double = myPoint.X / ProgressBar1.ActualWidth * MediaElement1.NaturalDuration.TimeSpan.TotalSeconds
100    MediaElement1.Position = TimeSpan.FromSeconds(mySecond)
101  End Sub
102 
103■エミュレーターのBack(←)ボタンのイベントを上書きする処理
104エミュレーターの持っている本来のBack処理を、e.Cancel=Trueで無効とします。
105NavigationService.NavigateメソッドでMainPage.xamlに遷移します。その際panoramaIndexというキーワードに1の値を渡しています。パノラマページのインデックスは0から開始するため、1を渡すと、2ページ目の曲名の一覧が表示されたページに戻ります。
106このBackボタンのイベントを上書きする処理を記述していないと、エミュレーターのBack(←)をクリックした際エラーが発生しますので、注意してください。
107Protected Overrides Subと入力すると、インテリセンス機能が働き、イベントの一覧が表示されますので、その中から選択してください。
108  Protected Overrides Sub OnBackKeyPress(ByVal e As System.ComponentModel.CancelEventArgs)
109    e.Cancel = True
110    dt.Stop()
111    NavigationService.Navigate(New Uri("/MainPage.xaml?panoramaIndex=1", UriKind.Relative))
112    MyBase.OnBackKeyPress(e)
113  End Sub
114End Class

去る2011年7月16日に「日本経済新聞 電子版」にて、Windows Phone 7搭載の機種が、8月末にもKDDI(au)から発売されるという報道がされました。Windows Phone Mangoを採用した端末としては世界最初の発売となるようです(詳細についてはKDDIの正式発表を待つのが賢明でしょう)。

四国の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メルマガ会員のサービス内容を見る

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