DataGridのデータをマルチ選択、カンマ区切りで保存する

2010年8月27日(金)
PROJECT KySS

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

リスト4のようにロジックコードを記述します。

リスト4: ロジックコード(MainPage.xaml.vb)

1<!--//--><![CDATA[// ><!--
2 
3Option Strict On
4 
5//--><!

LINQ to XMLでXMLを処理するクラスの含まれるSystem.Xml.Linq名前空間をインポートします。StringBuilderクラスを使って文字列の追加を行いますので、このクラスの含まれるSystem.Text名前空間をインポートします。また、ファイルの入出力に関するクラスの含まれるSystem.IO名前空間もインポートしておきます。

1<!--//--><![CDATA[// ><!--
2 
3Imports System.Xml.Linq
4Imports System.Text
5Imports System.IO
6 
7//--><!

PersonalInfoクラス内に「氏名、年齢、住所、勤務先」のプロパティを定義しておきます。

01<!--//--><![CDATA[// ><!--
02 
03Public Class PersonalInfo
04    Public Property 氏名 As String
05    Public Property 年齢 As String
06    Public Property 住所 As String
07    Public Property 勤務先 As String
08End Class
09~コード略~
10 
11//--><!

新しいStringBuilderのインスタンス、myDataとgridHeaderメンバ変数を宣言します。StringBuilderクラスは、文字を追加、削除、置換または挿入して値を作成した後に、その値を変更できるクラスです。

1<!--//--><![CDATA[// ><!--
2 
3    Dim myData As New StringBuilder
4    Dim gridHeader As New StringBuilder
5    Dim _gridHeader As String
6 
7//--><!

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

XElement.LoadメソッドでXML文書ファイル(sampleData.xml)を読み込みます。要素のコレクションを取得するクエリ(query)を定義します。PersonalInfoクラスの新しいリストとして作成するmyPersonalInfoを宣言します。

queryを実行します。クエリコレクション内を反覆処理しながら、PersonalInfoクラスの各プロパティ(「氏名」、「年齢」、「住所」、「勤務先」)に、、、、要素の値を追加します。DataGridコントロールのItemsSourceにmyPersonalInfoオブジェクト指定します。DataGridコントロールにXMLデータがバインドされて表示されます。

StringBuilderクラスのインスタンスとして生成した、gridHeaderオブジェクトに、AppendメソッドでDataGridのヘッダの値を、カンマ区切りで、追加しておきます。このままだと末尾にもカンマが追加されますので、末尾のカンマは削除する処理を行います。

01<!--//--><![CDATA[// ><!--
02 
03    Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
04        Dim xmldoc As XElement = XElement.Load("sampleData.xml")
05        Dim query = From c In xmldoc.Descendants("情報") Select c
06        Dim myPersonalInfo As New List(Of PersonalInfo)
07        For Each result In query
08            With myPersonalInfo
09                .Add(New PersonalInfo With {.氏名 = result.Element("氏名").Value,
10                    .年齢 = result.Element("年齢").Value,
11                    .住所 = result.Element("住所").Value,
12                    .勤務先 = result.Element("勤務先").Value})
13            End With
14            DataGrid1.ItemsSource = myPersonalInfo
15        Next
16        Dim i As Integer = 0
17        For Each myHeader In DataGrid1.Columns
18            gridHeader.Append(myHeader.Header.ToString).Append(",")
19        Next
20        Dim hearderLen As Integer = Len(gridHeader.ToString) - 1
21        _gridHeader = Left(gridHeader.ToString, hearderLen)
22    End Sub
23 
24//--><!

■DataGridコントロールのデータ項目が選択された時に発生するイベント

選択されたPersonalInfoクラスの「氏名」、「年齢」、「住所」、「勤務先」をカンマ区切りで、StringBuilderのインスタンスmyDataにAppendメソッドで追加していきます。

01<!--//--><![CDATA[// ><!--
02 
03    Private Sub DataGrid1_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles DataGrid1.SelectionChanged
04        Try
05            Dim myInfo As PersonalInfo = DirectCast(e.AddedItems(0), PersonalInfo)
06            myData.Append(myInfo.氏名).Append(",").Append(myInfo.年齢).Append(",").Append(myInfo.住所).Append(",").Append(myInfo.勤務先).Append(vbCrLf)
07            Catch
08            Exit Sub
09        End Try
10    End Sub
11 
12//--><!

■ContextMenuから「コピー」が選択された時の処理

myData変数内の文字列をクリップボードに格納します。SetTextメソッドはクリップボード内にUnicodeテキストを格納するメソッドです。

1<!--//--><![CDATA[// ><!--
2 
3    Private Sub Copy_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs)
4        If DataGrid1.SelectedIndex >= 0 Then
5            Clipboard.SetText(myData.ToString)
6        End If
7    End Sub
8 
9//--><!

■ContextMenuから「貼り付け」が選択された時の処理

クリップボードの中が空でない場合は、GetTextメソッドでクリップボード内のデータにアクセスして、TextBox1内にデータを貼り付けます。

1<!--//--><![CDATA[// ><!--
2 
3    Private Sub Paste_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs)
4        If Clipboard.ContainsText() = True Then
5            TextBox1.Text = Clipboard.GetText()
6        End If
7    End Sub
8 
9//--><!

■DataGridコントロール内で、マウスの右ボタンが押されたときの処理

マウスの右ボタンでクリックされたXとYの位置を、変数myXとmyYに格納しておきます。 SetValueメソッドで、ContextMenuコントロールの表示位置を設定し、ContextMenuコントロールのIsOpenメソッドにTrueを指定してContextMenuを表示します。アイコン付きのメニュー項目(コピー、貼り付け)が表示されます。

01<!--//--><![CDATA[// ><!--
02 
03    Private Sub DataGrid1_MouseRightButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles DataGrid1.MouseRightButtonDown
04        Dim myPosition = e.GetPosition(Nothing)
05        Dim myX = myPosition.X
06        Dim myY = myPosition.Y
07        ContextMenu1.SetValue(Canvas.LeftProperty, myX)
08        ContextMenu1.SetValue(Canvas.TopProperty, myY)
09        ContextMenu1.IsOpen = True
10    End Sub
11 
12//--><!

■TextBoxコントロール内で、マウスの右ボタンが押されたときの処理

e.Handled = Trueと記述することで、Silverlight標準の「Silverlight(S)」のメニューが出なくなります。

マウスの右ボタンでクリックされたXとYの位置を、変数myXとmyYに格納しておきます。 SetValueメソッドで、ContextMenuコントロールの表示位置を設定し、ContextMenuコントロールのIsOpenメソッドにTrueを指定してContextMenuを表示します。アイコン付きのメニュー項目(コピー、貼り付け)が表示されます。[保存]ボタンの使用を可能にします。

01<!--//--><![CDATA[// ><!--
02 
03    Private Sub TextBox1_MouseRightButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles TextBox1.MouseRightButtonDown
04        e.Handled = True
05        Dim myPosition = e.GetPosition(Nothing)
06        Dim myX = myPosition.X
07        Dim myY = myPosition.Y
08        ContextMenu1.SetValue(Canvas.LeftProperty, myX)
09        ContextMenu1.SetValue(Canvas.TopProperty, myY)
10        ContextMenu1.IsOpen = True
11        Button1.IsEnabled = True
12    End Sub
13 
14//--><!

■[保存]ボタンをクリックしたときの処理

新しいSaveFileDialogのインスタンス、mySaveFileDialogオブジェクトを生成します。 フィルタにCSVファイルを指定し、DefaultExtプロパティに既定のファイル名拡張子csvを指定します。

mySaveFileDialogオブジェクトのShowDialogメソッドがTrueの場合は、mySaveFileDialogの、OpenFileメソッドで開かれたファイルと文字コードで初期化された、新しいStreamWriterのインスタンスwriterオブジェクトを生成します。Writeメソッドでヘッダを追加してTextBox1コントロールの内容をストリームに書き込みます。StreamWriterを閉じ、保存した旨のダイアログボックスを表示します。

01<!--//--><![CDATA[// ><!--
02 
03    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
04 
05        Dim mySaveDialog As New SaveFileDialog
06        mySaveDialog.Filter = "Text Files(.csv)|*.csv|All Files|*.*"
07        mySaveDialog.DefaultExt = "csv"
08        If mySaveDialog.ShowDialog = True Then
09            Dim writer As StreamWriter = New StreamWriter(mySaveDialog.OpenFile, System.Text.Encoding.UTF8)
10            writer.Write(_gridHeader & vbCrLf & TextBox1.Text)
11            writer.Flush()
12            writer.Close()
13            MessageBox.Show(mySaveDialog.SafeFileName & "を保存しました。")
14        Else
15            MessageBox.Show("保存を中止しました。")
16            Exit Sub
17        End If
18    End Sub
19~コード略~
20 
21//--><!

全10回の連載はこれで終わりです。いかがでしたか?

関心を持ったサンプルを、ぜひ実際に開発して、Silverlight 4の可能性を考えてみていただければと思います。また、前回、今回のサンプルとも、データにXMLを使用しましたが、WCF RIA Servicesを使えば、SQL Serverデータベースの利用も可能です。機会があれば、またご紹介したいと思います。

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

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