Windows8のストア画面で手軽に時計を表示するサンプル

2013年4月19日(金)
薬師寺 国安

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

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

リスト1 (MainWindow.xaml.vb)

Option Strict On

タイマーの機能を提供するクラスの含まれるWindows.System.Threading名前空間をインポートします。

Imports Windows.System.Threading

文字色等を設定する機能の含まれるWindows.UI名前空間をインポートします。

Imports Windows.UI

ファイル、フォルダ、およびアプリケーションの設定を管理するクラスの含まれる、Windows.Storage名前空間をインポートします。

Imports Windows.Storage

シーケンシャルとランダムアクセスストリームから読み書きをサポートするクラスの含まれる、Windows.Storage.Streams名前空間をインポートします。

Imports Windows.Storage.Streams

Public NotInheritable Class MainPage
  Inherits Page

  Dim myColorInfo As String

タイマーを表すDispatcherTimerクラスの新しいインスタンスmyTimerをメンバ変数として宣言します。

  Dim myTimer As New DispatcherTimer

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

ピクチャライブラリにアクセスします。
CreateFolderAsyncメソッドでピクチャライブラリ内にXMLというフォルダを作成します。CreationCollisionOption.OpenIfExistsを指定しておくと、同名フォルダが存在する場合は、そのフォルダ名を返し、ない場合は新規に作成してくれます。

GetFilesAsyncメソッドでピクチャライブラリ内のXMLサブフォルダ内のファイルを取得します。CountプロパティでXMLサブフォルダ内にファイルが存在する場合は、GetFileAsyncメソッドでmyColor.xmlを取得します。
取得したXMLファイルをOpenAsyncメソッドで、読み込み専用で開きます。
新しいStreamReaderクラスのインスタンスreaderオブジェクトを作成し、取得したXMLファイルをUTF-8エンコーディングで読み込みます。
ReadToEndメソッドで読み込んだ結果を変数resultに格納します。

XElement.Parseメソッドで読み込んだXMLを格納しているresult変数の内容を文字列として読み込みます。
読み込んだXMLの要素の値を変数_Colorに格納します。

変数_Colorに格納された値で条件分岐を行います。変数_Colorに格納された色をCasCadingTextBlockのForegroundに指定し、_Color変数に対応するRadioButtonにチェックを付けます。

CasCadingTextBlockのTextプロパティに現在の年月日時間分秒を指定します。タイマーの発生する間隔を10秒とします。
AddHandlerステートメントで、タイマーのTickイベントにイベントハンドラを追加します。Tickイベントは、指定したタイマーの間隔が経過し、タイマーが有効である場合に発生するイベントです。
イベントハンドラ内ではCascadhingTextBlockのTextプロパティに現在の年月日時間分秒を指定し、BeginCascadingTransitionAsyncメソッドでアニメーションを開始します。
Startメソッドでタイマーを開始します。非同期処理で実行されるため、メソッドの先頭にAsyncを追加します。

  Protected Overrides Async Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
      Dim result As String
      Dim _Color As String
      Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary
      Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("XML", CreationCollisionOption.OpenIfExists)
      Dim myFile = Await mySubFolder.GetFilesAsync()
      If myFile.Count> 0 Then
        Dim xmldoc As StorageFile = Await mySubFolder.GetFileAsync("myColor.xml")
        Using myStream As IRandomAccessStream = Await xmldoc.OpenAsync(FileAccessMode.Read)
          Using reader As StreamReader = New StreamReader(myStream.AsStream, System.Text.Encoding.UTF8)
            result = reader.ReadToEnd
          End Using
        End Using
      Dim doc As XElement = XElement.Parse(result)
      _Color = doc.Descendants("Color").Value
      Select Case _Color
        Case "Red"
          CascadingTextBlock1.Foreground = New SolidColorBrush(Colors.Red)
          redRadioButton.IsChecked = True
        Case "Blue"
          CascadingTextBlock1.Foreground = New SolidColorBrush(Colors.Blue)
          blueRadioButton.IsChecked = True
        Case "Green"
          CascadingTextBlock1.Foreground = New SolidColorBrush(Colors.Green)
          greenRadioButton.IsChecked = True
        Case "White"
          CascadingTextBlock1.Foreground = New SolidColorBrush(Colors.White)
          whiteRadioButton.IsChecked = True
        Case "Yellow"
          CascadingTextBlock1.Foreground = New SolidColorBrush(Colors.Yellow)
          goldRadioButton.IsChecked = True
      End Select
    End If
    CascadingTextBlock1.Text = DateTime.Now.ToString
    myTimer.Interval = New TimeSpan(0, 0, 10)

    AddHandlermyTimer.Tick, Sub()
                            CascadingTextBlock1.AnimateOnLoaded = True
                            CascadingTextBlock1.Text = DateTime.Now.ToString
                   
                            CascadingTextBlock1.BeginCascadingTransitionAsync()
                          End Sub
    myTimer.Start()
    
  End Sub

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

Stopメソッドでタイマーを停止します。

  Protected Overrides Sub OnNavigatedFrom(e As Navigation.NavigationEventArgs)
    myTimer.Stop()
    MyBase.OnNavigatedFrom(e)
  End Sub

[Settings]ボタンがクリックされた時の処理

非表示になっていたStackPanelを表示します。色を選択するRadioButtonと[Save]ボタンが表示されます。

  Private Sub settingButton_Click(sender As Object, e As RoutedEventArgs) Handles settingButton.Click

    StackPanel1.Visibility = Windows.UI.Xaml.Visibility.Visible

  End Sub

「赤」のRadioButtonにチェックが付けられた時の処理

ForegroundプロパティにRedを指定し、メンバ変数myColorInfoにRedを格納します。

  Private Sub redRadioButton_Checked(sender As Object, e As RoutedEventArgs) Handles redRadioButton.Checked
    CascadingTextBlock1.Foreground = New SolidColorBrush(Colors.Red)
    myColorInfo = "Red"
  End Sub

「青」のRadioButtonにチェックが付けられた時の処理

  Private Sub blueRadioButton_Checked(sender As Object, e As RoutedEventArgs) Handles blueRadioButton.Checked
    CascadingTextBlock1.Foreground = New SolidColorBrush(Colors.Blue)
    myColorInfo = "Blue"
  End Sub

「緑」のRadioButtonにチェックが付けられた時の処理

  Private Sub greenRadioButton_Checked(sender As Object, e As RoutedEventArgs) Handles greenRadioButton.Checked
    CascadingTextBlock1.Foreground = New SolidColorBrush(Colors.Green)
    myColorInfo = "Green"
  End Sub

「白」のRadioButtonにチェックが付けられた時の処理

  Private Sub whiteRadioButton_Checked(sender As Object, e As RoutedEventArgs) Handles whiteRadioButton.Checked
    CascadingTextBlock1.Foreground = New SolidColorBrush(Colors.White)
    myColorInfo = "White"
  End Sub

「黄」のRadioButtonにチェックが付けられた時の処理

  Private Sub goldRadioButton_Checked(sender As Object, e As RoutedEventArgs) Handles goldRadioButton.Checked
    CascadingTextBlock1.Foreground = New SolidColorBrush(Colors.Yellow)
    myColorInfo = "Yellow"
  End Sub

[Save]ボタンがクリックされた時の処理

Visual Basic の埋め込み式を用いて、ルート要素、その子要素としてを作成し、埋め込み式の構文であるを用いてメンバ変数myColorInfoの値を指定します。これは ASP.NET で使用される構文と同じです。作成したXML文書を変数colorXmlに格納します。

XElement.ParseメソッドでcolorXml変数の値を文字列として読み込みます。読み込んだ結果XMLの値を変数resultに格納しておきます。

ピクチャライブラリにアクセスします。CreateFolderAsyncメソッドでピクチャライブラリ内にXMLというフォルダを作成します。CreationCollisionOption.OpenIfExistsを指定しておくと、同名フォルダが存在する場合は、そのフォルダ名を返し、ない場合は新規に作成してくれます。また、CreateFileAsyncメソッドでピクチャライブラリのXMLサブフォルダ内にmyColor.xmlというファイルを作成します。CreationCollisionOption.ReplaceExistingと指定し、既に同名のファイルがある場合は上書きします。OpenAsyncメソッドで作成したmyColor.xmlを「読み取り/書き込み」モードで開き、入出力データへの、ランダムアクセスをサポートするIRandomAccessStreamインターフェース型のmyStreamで参照します。

データを出力ストリームに書き込む、新しいDataWriterのインスタンスをmyStreamで初期化し、writerオブジェクトを作成します。出力ストリームのUnicode文字エンコードを設定する、UnicodeEncodingプロパティにUtf8を指定します。Writeメソッドで出力ストリームにresult変数の値を書き込みます。StoreAsyncメソッドでバッキングストアにバッファーのデータをコミットします。StackPanelを非表示にし、文字色の選択を非表示にします。非同期処理で行われるため、メソッドの先頭にAsyncを追加します。

  Private Async Sub saveButton_Click(sender As Object, e As RoutedEventArgs) Handles saveButton.Click
    Dim colorXml As XElement = <ColorInfo><Color><%= myColorInfo %></Color></ColorInfo>
    Dim xmldoc As XElement = XElement.Parse(colorXml.ToString)
    Dim result As String = xmldoc.ToString
 
    Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary
    Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("XML", CreationCollisionOption.OpenIfExists)
    Dim myXmlFile As StorageFile = Await mySubFolder.CreateFileAsync("myColor.xml", CreationCollisionOption.ReplaceExisting)
    Using myStream As IRandomAccessStream = Await myXmlFile.OpenAsync(FileAccessMode.ReadWrite)
      Dim writer As DataWriter = New DataWriter(myStream)
      writer.UnicodeEncoding = UnicodeEncoding.Utf8
      writer.WriteString(result)
      Await writer.StoreAsync
    End Using
    StackPanel1.Visibility = Xaml.Visibility.Collapsed
  End Sub

CountdownControlが指定され、数をカウントし終えた場合の処理

CountdownControlを非表示にします。

  Private Sub CountdownControl1_CountdownComplete(sender As Object, e As RoutedEventArgs) Handles CountdownControl1.CountdownComplete
    CountdownControl1.Visibility = Xaml.Visibility.Collapsed
  End Sub
End Class

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

  • Windows 8のWindowsストア画面で手軽に時計を表示させるためのサンプル

薬師寺国安事務所

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

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