パノラマページを作成する(後編)
2011年7月22日(金)
ソリューションエクスプローラー内のseiSong.xamlを展開し、表示されるseiSong.xaml.vbをダブルクリックしてリスト2のロジックコードを記述します。
リスト2 曲を再生する処理 (seiSong.xaml.vb)
Option Strict On Imports System.Xml.Linq タイマーの機能を提供するクラスの含まれる、System.Windows.Threading名前空間をインポートしておきます。 Imports System.Windows.Threading 画像を表示するのに必要な機能の含まれる、System.Windows.Media.Imaging名前空間をインポートしておきます。 Imports System.Windows.Media.Imaging Partial Public Class seiSong Inherits PhoneApplicationPage ~コード略~ タイマーを表すDispatcherTimerクラスのインスタンスdtオブジェクトを、メンバ変数として宣言します。 Dim dt As New DispatcherTimer Dim no As Boolean = False ReadXmldocクラスのインスタンスmyReadXmldocオブジェクトをメンバ変数として宣言します。 Dim myReadXmldoc As New ReadXmldoc ■画面の遷移で移動した時に最初に呼ばれるイベント ここで、MainPage.xamlから渡された文字データを受け取ります。文字データはNavigationContextのQueryStringにDictionary として提供されます。送信時のキーワード(この場合Index)を基に渡された文字列情報を、myParam(“Index”)として取得します。 myParam(“Index”)の値を数値に変換して、変数Indexに格納します。 ReadXmldocクラスのインスタンスmyReadXmldocでseiSong関数を呼び出します。Descendantsメソッドで、変数Indexに該当する<Music>要素の値を取得し、変数myTitleに格納します。 同じく、変数Indexに該当する<Music>要素の属性”Uri”の値を取得し、変数mySongに格納します。 x:NameがPageTitleというTextBlockにmyTitleの値を表示します。曲名が表示されます。 MediaElementのSourceプロパティに絶対URIとして、変数mySongの値を指定します。前編のリスト1の、SeiMusic.xmlの”Uri”属性に記述されたアドレスにアクセスします。 Volumeプロパティの値に1を指定します。Volumeプロパティには0~1の値を指定できます。規定値は0.5です。 変数Indexに該当する<Music>要素の属性”Image”値を取得し、変数imageNameに格納します。 ImageのSourceプロパティに、画像を置いてあるImageフォルダーを連結したimageNameの値を相対URIで指定します。 Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs) Dim myParam As IDictionary(Of String, String) = NavigationContext.QueryString Dim Index As Integer = Integer.Parse(myParam("Index")) Dim myTitle As String = myReadXmldoc.seiSong.Descendants("Music")(Index).Value Dim mySong As String = myReadXmldoc.seiSong.Descendants("Music")(Index).Attribute("Uri").Value PageTitle.Text = myTitle MediaElement1.Source = New Uri(mySong, UriKind.Absolute) MediaElement1.Volume = 1 Dim imageName As String = myReadXmldoc.seiSong.Descendants("Music")(Index).Attribute("Image").Value Image1.Source = New BitmapImage(New Uri("Image/" & imageName, UriKind.Relative)) MyBase.OnNavigatedTo(e) End Sub ■メディアストリームが検証されて開かれ、ファイル ヘッダーが読み取られると発生する処理 AddHandlerメソッドで、タイマー間隔が経過すると発生するTickイベントに、イベントハンドラを追加します。イベントハンドラ内では下記の処理を行います。 タイマーの経過に伴い、ProgressBar を進行させます。経過時間を示す MediaElement.Position.TotalSecondsを、MediaElement.NaturalDuration.TimeSpan.TotalSeconds で取得したメディア・ファイルの継続時間で除算することにより、メディア・ファイルに対する再生時間の比率を求め、ProgressBarのデフォルトのMaximumである100を乗算して、ProgressBar の値に設定します。これで、曲の再生と同期してプログレスバーが進行します。 Startメソッドでタイマーを開始します。 Private Sub MediaElement1_MediaOpened(sender As Object, e As System.Windows.RoutedEventArgs) Handles MediaElement1.MediaOpened AddHandler dt.Tick, Sub() ProgressBar1.Value = MediaElement1.Position.TotalSeconds / MediaElement1.NaturalDuration.TimeSpan.TotalSeconds * 100 End Sub dt.Start() End Sub ■曲の再生が完了した時の処理 [Pause]ボタンを使用不可とし、[Play]ボタンを使用可能にします。ブール型変数noにTrueを指定します。タイマーを中止します。 Private Sub MediaElement1_MediaEnded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles MediaElement1.MediaEnded PauseButton.IsEnabled = False PlayButton.IsEnabled = True no = True dt.Stop() End Sub ■[Pause]ボタンがクリックされた時の処理 曲の再生を休止し、[Play]ボタンを使用可能、[Pause]ボタンを使用不可とします。 Private Sub PauseButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles PauseButton.Click MediaElement1.Pause() PlayButton.IsEnabled = True PauseButton.IsEnabled = False End Sub ■[Playボタンがクリックされた時の処理 ブール型変数noの値で条件分岐を行います。noの値がTrueの時、つまり、曲が最後まで再生し切った場合は、PositionプロパティにTimeSpan.Zeroと指定し、再生開始位置を0秒時点に戻します。ProgressBarの値を0で初期化し、タイマーを開始します。no変数にFalseを指定します。 曲を再生し、[Play]ボタンを使用不可、[Pause]ボタンを使用可とします。 Private Sub PlayButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles PlayButton.Click If no = True Then MediaElement1.Position = TimeSpan.Zero ProgressBar1.Value = 0 dt.Start() no = False End If MediaElement1.Play() PlayButton.IsEnabled = False PauseButton.IsEnabled = True End Sub ■[Topに戻る]ボタンがクリックされた時の処理 タイマーを中止し、MainPage.xamlに遷移します。 Private Sub TopButton_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles TopButton.Click dt.Stop() Me.NavigationService.Navigate(New Uri("/MainPage.xaml", UriKind.Relative)) End Sub ■プログレスバーの上でマウスの左ボタンが押下された時の処理 GetPosition メソッドで座標を取得し、ProgressBar の幅に対する比率を求め、メディアの継続時間に乗算して、クリックした位置に相当するメディアの秒数を計算します。TimeSpan.FromSeconds を用いて、これを再生開始位置として指定します。 Private Sub ProgressBar1_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles ProgressBar1.MouseLeftButtonDown Dim myPoint As New Point myPoint = e.GetPosition(ProgressBar1) Dim mySecond As Double = myPoint.X / ProgressBar1.ActualWidth * MediaElement1.NaturalDuration.TimeSpan.TotalSeconds MediaElement1.Position = TimeSpan.FromSeconds(mySecond) End Sub ■エミュレーターのBack(←)ボタンのイベントを上書きする処理 エミュレーターの持っている本来のBack処理を、e.Cancel=Trueで無効とします。 NavigationService.NavigateメソッドでMainPage.xamlに遷移します。その際panoramaIndexというキーワードに1の値を渡しています。パノラマページのインデックスは0から開始するため、1を渡すと、2ページ目の曲名の一覧が表示されたページに戻ります。 このBackボタンのイベントを上書きする処理を記述していないと、エミュレーターのBack(←)をクリックした際エラーが発生しますので、注意してください。 Protected Overrides Subと入力すると、インテリセンス機能が働き、イベントの一覧が表示されますので、その中から選択してください。 Protected Overrides Sub OnBackKeyPress(ByVal e As System.ComponentModel.CancelEventArgs) e.Cancel = True dt.Stop() NavigationService.Navigate(New Uri("/MainPage.xaml?panoramaIndex=1", UriKind.Relative)) MyBase.OnBackKeyPress(e) End Sub End Class
去る2011年7月16日に「日本経済新聞 電子版」にて、Windows Phone 7搭載の機種が、8月末にもKDDI(au)から発売されるという報道がされました。Windows Phone Mangoを採用した端末としては世界最初の発売となるようです(詳細についてはKDDIの正式発表を待つのが賢明でしょう)。
連載バックナンバー
Think ITメルマガ会員登録受付中
Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。