PR

データを保存し氏名から詳細情報を表示する

2011年10月31日(月)
PROJECT KySS

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

未入力のデータがあれば警告メッセージを表示するErrorMessageプロシージャを実行します。
新しいWebClientのインスタンスmyWebClientオブジェクトを生成します。WebClientクラスは、データの送受信用のメソッドを提供するクラスです。
String またはUriとして指定したリソースをダウンロードする、DownloadStringAsyncメソッドで、サーバー上のpersonalInfo.xmlをダウンロードします。キャッシュから読み込まないように、常に新しいデータを読み込むよう、引数に現在の時間、分、秒を指定しています。
AddHandlerステートメントで、非同期のリソース ダウンロード操作の完了時に発生する、DwonloadStringCompletedイベントに、イベントハンドラを追加します。イベントハンドラ内では以下の処理を実行します。
Image1のSourceプロパティに指定されている画像のファイル名を取得します。
XElement.Parseメソッドでダウンロードした結果を読み込みます。読み込んだ結果はmyDocメンバ変数に格納されます。
<情報>要素を生成し、子要素として<氏名>要素を生成し、内容テキストにnameTextBoxの値を指定します。次に<電話>要素を生成し、内容テキストにtelTextBoxの値を指定します。<住所>要素を生成し、addressTextBoxの値を指定し、<電話>要素を生成して、telTextBoxの値を指定し、<メール>要素を生成して、mailTextBoxの値を指定し、<画像>要素を生成して、先に取得しておきたImage1の、Sourceプロパティの値をToStringで文字列に変換して指定します。
生成したXMLをAddメソッドでmyDocに追加します。
  Private Sub okButton_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles okButton.Click
    ErrorMessage()
    Dim myWebClient As New WebClient
    AddHandler myWebClient.DownloadStringCompleted, Sub(resultSender As Object, resultArgs As DownloadStringCompletedEventArgs)
                If resultArgs.Error Is Nothing = False Then
                         MessageBox.Show("XMLファイルが見つかりません")
                         Exit Sub
                Else
                  Dim myImage As BitmapImage = DirectCast(Image1.Source, BitmapImage)
                  Dim imageUri As Uri = myImage.UriSource
                  myDoc = XElement.Parse(resultArgs.Result)
                  readXml = New XElement("情報",
                            New XElement("氏名", nameTextBox.Text),
                            New XElement("住所", addressTextBox.Text),
                            New XElement("電話", telTextBox.Text),
                            New XElement("メール", mailTextBox.Text),
                            New XElement("画像", imageUri.ToString))
                            myDoc.Add(readXml)
                  End If
                End Sub
              myWebClient.DownloadStringAsync(New Uri(String.Format("サーバーのURI/PersonalInfo_NET/SaveData/personalInfo.xml?myTime={0}", DateTime.Now.ToLongTimeString), UriKind.Absolute))
  End Sub

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

未入力のデータがあった場合に警告メッセージを表示するErrorMessageプロシージャを実行します。
生成したXMLを変数saveXmlDataに格納しておきます。
新しいWebClientのインスタンスmyWebClientオブジェクトを生成します。WebClientクラスは、データの送受信用のメソッドを提供するクラスです。
EncodingプロパティにUTF8を指定し、HeadersのContent-Typeに”text/xml;charset=utf-8”と指定します。
UploadStringAsyncメソッドで、生成したXML(saveXmlDataの値)をサーバーにアップロードし、サーバー上のDefault.aspx(後ほど作成方法を解説)を実行します。アップするサーバーのURIは各自のURIに変更してください。UploadStringAsyncメソッドは、指定したリソースに指定した文字列(この場合、生成したXMLデータ)をアップロードします。引数に現在の時間、分、秒を指定し、常に新しいデータをアップロードします。
AddHandlerステートメントで、非同期の文字列アップロード操作の完了時に発生する、UploadStringCompletedイベントに、イベントハンドラを追加します。イベントハンドラ内では、保存した旨のメッセージを表示し、サーバーからperonalInfo.xmlを読み込み、その内容を表示するDownLoadXmlDataプロシージャを実行します。
※サーバーに配置した、PersonalInfo_NETのASP.NETファイルのアクセス許可やIISの設定等については、各自が行ってください。
各入力ボックス内をクリアし、画像はデフォルトの画像を読み込みます。[保存]ボタンの使用を不可とします。
  Private Sub saveButton_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles saveButton.Click
    ErrorMessage()
    Dim saveXmlData As String
    saveXmlData = myDoc.ToString
 
    Dim webClient As New WebClient
    With webClient
      .Encoding = System.Text.Encoding.UTF8
      .Headers("content-type") = "text/xml; charset=utf-8"
    End With
 
    AddHandler webClient.UploadStringCompleted, Sub(resultSender As Object, resultArgs As UploadStringCompletedEventArgs)
                               MessageBox.Show("保存しました")
                               DownloadXmlData()
                 End Sub
    webClient.UploadStringAsync(New Uri(String.Format("サーバーのURI/PersonalInfo_NET/Default.aspx?myTime={0}", DateTime.Now.ToLongTimeString), UriKind.Absolute), saveXmlData)
    nameTextBox.Text = String.Empty
    addressTextBox.Text = String.Empty
    telTextBox.Text = String.Empty
    mailTextBox.Text = String.Empty
    Image1.Source = New BitmapImage(New Uri("Image/未設定.jpg", UriKind.Relative))
    saveButton.IsEnabled = False
    okButton.IsEnabled = True
    saveButton.IsEnabled = False
  End Sub

サーバーからperonalInfo.xmlを読み込み、その内容を表示する処理

新しいWebClientのインスタンスmyWebClientオブジェクトを生成します。WebClientクラスは、データの送受信用のメソッドを提供するクラスです。
String またはUriとして指定したリソースをダウンロードする、DownloadStringAsyncメソッドで、サーバー上のpersonalInfo.xmlをダウンロードします。引数に現在の時間、分、秒を指定して、最新のXMLデータをダウンロードします。
AddHandlerステートメントで、非同期のリソース ダウンロード操作の完了時に発生する、DwonloadStringCompletedイベントに、イベントハンドラを追加します。ダウンロードでエラーが発生した場合はメッセージを表示します。それ以外は、XElement.Parseメソッドでダウンロードした結果(resultArgs.Result)を読み込みます。
personalInfoクラス型の新しいリストであるmyPersonalInfoオブジェクトを作成します。Descendants メソッドで、子孫要素である全ての <情報> 要素のコレクションに対して、各要素を変数 result に格納しながら、personalInfo クラスの「氏名」、「住所」、「電話」、「メール」、「画像」プロパティに、<氏名>、<住所>、<電話>、<メール>、<画像>要素の内容テキストを指定し、AddメソッドでmyPersonalInfoオブジェクトに追加していきます。3ページ目に配置したListBox(dataListBox)のItemsSourceにmyPersonalInfoオブジェクトを指定します。「画像」と「氏名」の一覧が表示されます。
  Private Sub DownloadXmlData()
    Dim myWebClient As New WebClient
    AddHandler myWebClient.DownloadStringCompleted, Sub(resultSender As Object, resultArgs As DownloadStringCompletedEventArgs)
        If resultArgs.Error Is Nothing = False Then
              MessageBox.Show("XMLファイルが見つかりません")
            Exit Sub
        Else
            Dim myDoc As XElement = XElement.Parse(resultArgs.Result)
            Dim myPersonalInfo As New List(Of personalInfo)
            For Each result In From c In myDoc.Descendants("情報") Select c
              With myPersonalInfo
              .Add(New personalInfo With {.氏名 = result.Element("氏名").Value,
                                          .住所 = result.Element("住所").Value,
                                          .電話 = result.Element("電話").Value,
                                          .メール = result.Element("メール").Value,
                                          .画像 = result.Element("画像").Value})
              End With
            Next
              dataListBox.ItemsSource = myPersonalInfo
        End If
      End Sub
    myWebClient.DownloadStringAsync(New Uri(String.Format("サーバーのURI/PersonalInfo_NET/SaveData/personalInfo.xml?myTime={0}", DateTime.Now.ToLongTimeString), UriKind.Absolute))
  End Sub

3ページ目の「画像」と「氏名」の一覧から任意の項目が選択された時の処理

DirectCastでdataListBoxより選択された項目をpersonalInfoクラスにキャストし、「氏名」、「住所」、「電話」、「メール」、「画像」プロパティの値を取得して各変数に格納しておきます。NavigationService.Navigateメソッドで、変数に格納した値を引数にpersonalInfoPage.xamlに遷移します。Try~Catch~End Tryで例外処理を行っていないと、personalInfoPage.xamlから、Back(←)ボタンで戻る際エラーが表示されてしまいます。
  Private Sub dataListBox_SelectionChanged(sender As Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles dataListBox.SelectionChanged
    Try
      Dim myName As String = DirectCast(dataListBox.SelectedItem, personalInfo).氏名
      Dim myAddress As String = DirectCast(dataListBox.SelectedItem, personalInfo).住所
      Dim myTel As String = DirectCast(dataListBox.SelectedItem, personalInfo).電話
      Dim myMail As String = DirectCast(dataListBox.SelectedItem, personalInfo).メール
      Dim myImage As String = DirectCast(dataListBox.SelectedItem, personalInfo).画像
      NavigationService.Navigate(New Uri(String.Format("/personalInfoPage.xaml?name={0}&address={1}&tel={2}&mail={3}&image={4}", myName, myAddress, myTel, myMail, myImage), UriKind.Relative))
    Catch
      Exit Sub
    End Try
  End Sub

未入力データがあった場合警告メッセージ表示する処理

   Private Sub ErrorMessage()
    If nameTextBox.Text = String.Empty OrElse addressTextBox.Text = String.Empty OrElse telTextBlock.Text = String.Empty OrElse mailTextBox.Text = String.Empty Then
      MessageBox.Show("データが未入力の箇所があります。")
      saveButton.IsEnabled = False
      Exit Sub
    Else
      saveButton.IsEnabled = True
    End If
  End Sub
End Class

ASP.NETページの作成(Personalnfo_NET)

VS2010のメニューから、「ファイル(F)/新規作成(N)/Webサイト(W)」と選択し、表示される画面から「ASP.NET Webサイト」を選択します。「webの場所(L)」に今回は「フォルダー名\PersonalInfo_NET」と指定し[OK]ボタンをクリックします。

ソリューションエクスプローラー内にSaveDataというフォルダーを作成し、個人情報>というルート要素だけのpersonalInfo.xmlを作成しておきます。

ソリューションエクスプローラー内のDefault.aspxを展開して表示される、Default.aspx.vbにリスト5のコードを記述します。
※このコードをサーバーに配置した際の、アクセス権の設定やIISの設定は各自が行ってください。

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

リスト5 (Default.aspx.vb)

Option Strict On
Imports System.IO
Partial Class _Default
  Inherits System.Web.UI.Page

ページが読み込まれた時の処理

サーバー上の物理パスを指定します。
StreamReaderクラスでPOSTされたデータ(Request.InputStream)を取得します。StreamReaderクラスは、特定のエンコーディングのバイトストリームを読み込むTextReader を実装するクラスです。
取得したデータの内容をReadToEndメソッドで読み取り、変数readStrに格納しておきます。
フォルダー名とファイル名(personalInfo.xml)を指定して、読み取ったデータをStreamWriterクラスのWriteメソッドで書き込みます。StreamWriterクラスは、文字を特定のエンコーディングでストリームに書き込むための TextWriterを実装するクラスです。
personalInfo.xmlにWindows Phoneから送信されたXMLデータが保存されます。
  Private Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    Dim filePath As String = Server.MapPath("./")
    Dim reader As New StreamReader(Me.Request.InputStream(), System.Text.Encoding.UTF8)
    Dim readStr As String = reader.ReadToEnd
    Dim writer As StreamWriter = New StreamWriter(filePath & "SaveData/" & "personalInfo.xml", False, System.Text.Encoding.UTF8)
    writer.Write(readStr)
    reader.Close()
    writer.Close()
    Response.Flush()
  End Sub
End Class
Think IT会員限定特典
  • 「データを保存し氏名から詳細情報を表示する」サンプルプログラム

四国の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のWebサイトにログインすることでさまざまな限定特典を入手できるようになります。

Think IT会員サービスの概要とメリットをチェック

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