パノラマページを作成する(後編)
2011年7月22日(金)

ソリューションエクスプローラー内のseiSong.xamlを展開し、表示されるseiSong.xaml.vbをダブルクリックしてリスト2のロジックコードを記述します。
リスト2 曲を再生する処理 (seiSong.xaml.vb)
001 | Option Strict On |
002 | Imports System.Xml.Linq |
003 |
004 | タイマーの機能を提供するクラスの含まれる、System.Windows.Threading名前空間をインポートしておきます。 |
005 | Imports System.Windows.Threading |
006 |
007 | 画像を表示するのに必要な機能の含まれる、System.Windows.Media.Imaging名前空間をインポートしておきます。 |
008 | Imports System.Windows.Media.Imaging |
009 | Partial 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 |
018 | ReadXmldocクラスのインスタンスmyReadXmldocオブジェクトをメンバ変数として宣言します。 |
019 | Dim myReadXmldoc As New ReadXmldoc |
020 |
021 | ■画面の遷移で移動した時に最初に呼ばれるイベント |
022 | ここで、MainPage.xamlから渡された文字データを受け取ります。文字データはNavigationContextのQueryStringにDictionary として提供されます。送信時のキーワード(この場合Index)を基に渡された文字列情報を、myParam(“Index”)として取得します。 |
023 | myParam(“Index”)の値を数値に変換して、変数Indexに格納します。 |
024 | ReadXmldocクラスのインスタンスmyReadXmldocでseiSong関数を呼び出します。Descendantsメソッドで、変数Indexに該当する<Music>要素の値を取得し、変数myTitleに格納します。 |
025 | 同じく、変数Indexに該当する<Music>要素の属性”Uri”の値を取得し、変数mySongに格納します。 |
026 | x:NameがPageTitleというTextBlockにmyTitleの値を表示します。曲名が表示されます。 |
027 | MediaElementのSourceプロパティに絶対URIとして、変数mySongの値を指定します。前編のリスト1の、SeiMusic.xmlの”Uri”属性に記述されたアドレスにアクセスします。 |
028 | Volumeプロパティの値に1を指定します。Volumeプロパティには0~1の値を指定できます。規定値は0.5です。 |
029 | 変数Indexに該当する<Music>要素の属性”Image”値を取得し、変数imageNameに格納します。 |
030 | Imageの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 | ■メディアストリームが検証されて開かれ、ファイル ヘッダーが読み取られると発生する処理 |
045 | AddHandlerメソッドで、タイマー間隔が経過すると発生するTickイベントに、イベントハンドラを追加します。イベントハンドラ内では下記の処理を行います。 |
046 | タイマーの経過に伴い、ProgressBar を進行させます。経過時間を示す MediaElement.Position.TotalSecondsを、MediaElement.NaturalDuration.TimeSpan.TotalSeconds で取得したメディア・ファイルの継続時間で除算することにより、メディア・ファイルに対する再生時間の比率を求め、ProgressBarのデフォルトのMaximumである100を乗算して、ProgressBar の値に設定します。これで、曲の再生と同期してプログレスバーが進行します。 |
047 | Startメソッドでタイマーを開始します。 |
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 | ■プログレスバーの上でマウスの左ボタンが押下された時の処理 |
095 | GetPosition メソッドで座標を取得し、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で無効とします。 |
105 | NavigationService.NavigateメソッドでMainPage.xamlに遷移します。その際panoramaIndexというキーワードに1の値を渡しています。パノラマページのインデックスは0から開始するため、1を渡すと、2ページ目の曲名の一覧が表示されたページに戻ります。 |
106 | このBackボタンのイベントを上書きする処理を記述していないと、エミュレーターのBack(←)をクリックした際エラーが発生しますので、注意してください。 |
107 | Protected 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 |
114 | End Class |
去る2011年7月16日に「日本経済新聞 電子版」にて、Windows Phone 7搭載の機種が、8月末にもKDDI(au)から発売されるという報道がされました。Windows Phone Mangoを採用した端末としては世界最初の発売となるようです(詳細についてはKDDIの正式発表を待つのが賢明でしょう)。
連載バックナンバー
Think ITメルマガ会員登録受付中
Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。