画面上の文字を指でなぞってマーカーを引くサンプル

2012年5月29日(火)
PROJECT KySS

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

リスト3 (MainPage.xaml.vb)

Option Strict On

インクの操作を行うクラスを提供する、System.Windows.Ink名前空間をインポートします。

Imports System.Windows.Ink

Imports System.Xml.Linq

仮想ファイルシステムを作成および使用するための型が含まれている、System.IO.IsolatedStorage名前空間をインポートします。分離ストレージによって、安全なクライアント側のストレージが提供されます。

Imports System.IO.IsolatedStorage

Imports System.IO

オブジェクトを、XML形式のドキュメントまたは、ストリームにシリアル化するために使用するクラスが含まれる、System.Xml.Serialization 名前空間をインポートします。

Imports System.Xml.Serialization

Partial Public Class MainPage
  Inherits PhoneApplicationPage
 
  ' コンストラクター
  Public Sub New()
    InitializeComponent()
  End Sub

単一のインクストローク(インクの一筆)を表す、Strokeクラス用メンバ変数myStrokeを宣言します。

 Dim myStroke As Stroke
 
 Dim xmldoc As XElement

[前]、[次]ボタンタップで増減するメンバ変数noを宣言し1で初期化しておきます。

  Dim no As Integer = 1

ページがアクティブになった時呼び出されるメソッド

島崎藤村の初恋の詩を記録したXML文書ファイルを読み込み表示する、DataShowプロシージャを実行します。

Protected Overrides Sub OnNavigatedTo(e As System.Windows.Navigation.NavigationEventArgs)
  DataShow()
  MyBase.OnNavigatedTo(e)
End Sub

島崎藤村の初恋の詩を記録したXML文書ファイルを読み込み表示するプロシージャ

ストロークをクリアしておきます。増減するメンバ変数noが1より大きい場合は、[前]ボタンの使用を可能にします。noが1または1より小さい場合は[前]ボタンの使用は不可とします。noが4の場合は[次]ボタンの使用は不可とし、それ以外の場合は使用可とします。

XElement.Loadメソッドでメンバ変数noに対応するXML文書ファイルを読み込みます。要素の値を取得しpoemTextBlockに表示します。

変数storageを、ファイルとディレクトリを格納している分離ストレージ領域を表すIsolateStorageFileクラスとして宣言します。DirectoryExitsメソッドでmyPoemというフォルダが存在しているかどうかをチェックし、存在していない場合は、CreateDirectoryメソッドでmyPoemというフォルダを作成します。

Path.CombineでmyPoemというフォルダとメンバ変数noに該当するXMLファイルを連結して、変数xmlFilePathに格納しておきます。同様に、MarkerInfoという文字列とメンバ変数noに該当するXMLファイルを連結して、変数markerPathに格納しておきます。このmarkerPathに格納されるXMLはマーカーの情報を記録したXMLです(リスト4参照)。

myPoemフォルダ内に、メンバ変数noに該当するXMLファイルが存在している場合の処理です。変数isolateを、ファイルとディレクトリを格納している分離ストレージ領域を表すIsolateStorageFileクラスとして宣言します。

分離ストレージ内のファイルを表すIsolatedStorageFileStreamクラス用オブジェクト変数のmyStream変数を用意し、IsolatedStorageFile.OpenFileメソッドで、指定したファイルアクセスを使用して指定したモードで開きます。開いたファイルをStreamReaderで読み込みます。ReadToEndメソッドでファイルの最後まで読み取り、変数readXmldoc変数に格納しておきます。読み込んだXMLテキストをParseメソッドでXElementとして読み込みます。読み込んだXML文書の要素値を取得して、poemTextBlockに表示します。

次にマーカー情報を読み込みます。myPoemフォルダ内にMarkerInfo+no.xmlファイルが存在している場合は、分離ストレージ内のファイルを表すIsolatedStorageFileStreamクラス用オブジェクト変数のStream変数を用意し、IsolatedStorageFile.OpenFileメソッドで、指定したファイルアクセスを使用して指定したモードで開きます。

Stroke オブジェクトのコレクションで初期化された、XmlSerializerクラスの新しいインスタンスを作成します。InkPresenterが表示するストロークに、指定した Stream に格納されているXMLドキュメントを逆シリアル化して、StrokeCollectionにキャストして指定します。

これで、詩にマーカーを引いて保存し、再度読み込んだ場合は、マーカーが引かれた状態で詩が読み込まれます。

リスト4 マーカー情報を記録したMarkerInfo.xmlの一部

<?xml version="1.0"?>
<ArrayOfStroke xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Stroke>
    <StylusPoints>
    <StylusPoint>
      <X>41</X>
      <Y>59</Y>
      <PressureFactor>0.5</PressureFactor>
    </StylusPoint>
    <StylusPoint>
      <X>46</X>
      <Y>57</Y>
      <PressureFactor>0.5</PressureFactor>
    </StylusPoint>
    <StylusPoint>
      <X>53</X>
      <Y>57</Y>
      <PressureFactor>0.5</PressureFactor>
    </StylusPoint>
    ~以下コード略~
  </Stroke>
</ArrayOfStroke>

※分離ストレージに保存されたファイルを確認する場合はWindows Phone Power Toolsを使用します。下記URLよりダウンロードできます。
→参照:Windows Phone Power Tools

  Private Sub DataShow()
    InkPresenter1.Strokes.Clear()
    If no > 1 Then prevButton.IsEnabled = True
    If no <= 1 Then prevButton.IsEnabled = False
    If no = 4 Then
      nextButton.IsEnabled = False
    Else
      nextButton.IsEnabled = True
    End If
 
    xmldoc = XElement.Load(no & ".xml")
    Dim contents As String = xmldoc.Descendants("内容").Value
    poemTextBlock.Text = contents
    Dim storage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication
 
    If storage.DirectoryExists("myPoem") = False Then
      storage.CreateDirectory("myPoem")
    End If
    Dim xmlFilePath As String = Path.Combine("myPoem", no & ".xml")
    Dim markerPath As String = Path.Combine("myPoem", "MarkerInfo" & no & ".xml")

    If storage.FileExists(xmlFilePath) = True Then

        Dim isolate As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication
 
        Using myStream As IsolatedStorageFileStream = storage.OpenFile(xmlFilePath, FileMode.Open, FileAccess.Read)
          Using reader As StreamReader = New StreamReader(myStream, System.Text.Encoding.UTF8)
            Dim readXmldoc As String = reader.ReadToEnd
            Dim doc As XElement = XElement.Parse(readXmldoc)
            Dim myContents As String = doc.Descendants("内容").Value
            poemTextBlock.Text = myContents
          End Using
        End Using
 
        'マーカーの読み込み
        If storage.FileExists(markerPath) = True Then
          Using Stream As IsolatedStorageFileStream = isolate.OpenFile(markerPath, FileMode.Open, FileAccess.Read)
            Dim xs As XmlSerializer = New XmlSerializer(GetType(StrokeCollection))
            InkPresenter1.Strokes = TryCast(xs.Deserialize(Stream), StrokeCollection)
          End Using
        End If
      End If
    End Sub
  • 画面を指でなぞってマーカーを引くサンプル

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

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