DataGridコントロールの新しい2つの機能を使う

2010年6月15日(火)
PROJECT KySS

DataGridコントロールのレイアウト

印刷用データが追加できたら、UserControlのPropertiesペインの[Layout]を展開して、Widthに800、Heightに600を指定します。

ToolboxからTextBlock、ComboBox、Button、DataGridコントロールを1個ずつレイアウトします。TextBlockのTextにはタイトルを指定しておきます。

ComboBoxコントロールのプロパティから、Itemsの(Collection) の横に表示されている[…]ボタンをクリックして、 「Collection Editor」を起動し、ComboBoxItemを2つ追加します。Contentプロパティには、それぞれ、「読み」、「年齢」と指定します。 「読み」のIsSelectedプロパティにはチェックを付け、デフォルトで「読み」が選択されるようにしておきます(図4)。

ComboBoxItemは、デフォルトで「読み」が選択されるようにしておく。

図4:ComboBoxItemは、デフォルトで「読み」が選択されるようにしておく。(クリックで拡大)

ButtonコントロールのContentプロパティには「すべて印刷」と指定します。

DataGridコントロールのPropertiesにあるColumnsの中の、AutoGenerateColumnsプロパティにチェックを付けて、自動的に列が生成されるようにしておきます。

すべてレイアウトすると図5のようになります。このレイアウトで書き出されるXAMLコードは省略します。

ComboBox、Button、DataGridコントロールをレイアウトした。

図5:ComboBox、Button、DataGridコントロールをレイアウトした。(クリックで拡大)

DataGridへのデータ表示と印刷の処理を記述する

レイアウトができたら、XMLデータをDataGridにデータを表示する処理と、印刷する処理を記述していきます。ロジック・コードはリスト2のようになります。

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

■名前空間の読み込みと、プロパティの定義
LINQ to XMLでXMLを処理するクラスの含まれる、System.Xml.Linq名前空間をインポートします。
印刷の機能を提供するクラスの含まれる、System.Windows.Printing名前空間をインポートします。
データをグループするためのクラスの含まれる、System.Windows.Data名前空間をインポートします。

Option Strict On
Imports System.Xml.Linq
Imports System.Windows.Printing
Imports System.Windows.Data

personalInfoクラス内に、「氏名、年齢、住所、勤務先」のプロパティを定義します。この処理は、前回と同じです。

Public Class personalInfo
  Property 氏名() As String
  Property 読み() As String
  Property 年齢() As String
  Property 住所() As String
  Property 勤務先() As String
End Class

CollectionViewSourceクラス用オブジェクト変数、myCollectionViewSourceをメンバ変数として定義します。 CollectionViewSourceクラスは、並べ替えおよびフィルタークエリに基づいて、コレクションの移動や表示を可能にするクラスです。
  Dim myCollectionViewSource As CollectionViewSource

■ページが読み込まれた時の処理
XElement.LoadメソッドでXML文書ファイル(sampleData_Group.xml)を読み込みます。要素のコレクションを取得するクエリ(query)を定義します。
personalInfoクラスのリストとして作成するmyPersonalInfoを宣言して、queryを実行します。
クエリコレクション内を反復処理しながら、Addメソッドで、personalInfoクラスの各プロパティ(「氏名、読み、年齢、住所、勤務先」)に、 XMLの各要素(、、、、)の値を追加します。 新しいCollectionViewSourceのインスタンスを生成し、myCollectionViewSourceオブジェクトのSourceプロパティにmyPersonalInfoオブジェクトを指定します。 Sourceプロパティにはビューの作成元のオブジェクトを指定することができます。

コレクション内の項目のグループ分けを記述するGroupDescriptionsコレクションに、Addメソッドで、「読み」で初期化された新しいPropertyGroupDescriptionを追加します。 PropertyGroupDescriptionクラスでは、プロパティ名を基準とした項目のグループ化を設定できます。DataGridコントロール(名前はDataGrid1)のItemsSourceプロパティに、 CollectionViewSourceのインスタンスに関連付けられているビューオブジェクトを指定します。これで、最初に「読み」でグループ化されたデータがDataGridに表示されます。


  Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
    Dim xmldoc As XElement = XElement.Load("sampleData_Group.xml")

    Dim query = From c In xmldoc.Descendants("情報") Select c
    Dim myPersonalInfo As New List(Of personalInfo)

    For Each result In query
      With myPersonalInfo
        .Add(New personalInfo With {.氏名 = result.Element("氏名").Value,
                                    .読み = result.Element("読み").Value,
                                    .年齢 = result.Element("年齢").Value,
                                    .住所 = result.Element("住所").Value,
                                    .勤務先 = result.Element("勤務先").Value})
      End With
      myCollectionViewSource = New CollectionViewSource
      myCollectionViewSource.Source = myPersonalInfo
    Next
    myCollectionViewSource.GroupDescriptions.Add(New PropertyGroupDescription("読み"))
    DataGrid1.ItemsSource = myCollectionViewSource.View
  End Sub

■ComboBoxコントロール内の項目が選択された時の処理
ComboBoxコントロールから選択された項目を変数myItemに格納します。グループ分けを記述するGroupDescriptionsコレクションに、 Addメソッドで、myItem(ComboBoxコントロールから選択された項目名)で初期化された新しいPropertyGroupDescriptionを追加します。
これで、ComboBoxコントロール内の項目に応じて、DataGridコントロール内のデータがグループ化されて表示されるようになります。


  Private Sub ComboBox1_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles ComboBox1.SelectionChanged
    If myCollectionViewSource Is Nothing = False Then
      myCollectionViewSource.GroupDescriptions.Clear()
      Dim myItem As String = DirectCast(ComboBox1.SelectedItem, ComboBoxItem).Content.ToString
      myCollectionViewSource.GroupDescriptions.Add(New PropertyGroupDescription(myItem))
    End If
  End Sub

■[印刷実行]ボタンをクリックした時の処理
新しいPrintDocumentのインスタンスmyPrintオブジェクトを生成します。PrintDocumentクラスはSilverlightアプリケーションの印刷機能を提供するクラスです。
印刷を実行するDataGrid_Printイベントを実行します。印刷が完了した時には、DataGrid_EndPrintイベントを実行します。 Printメソッドで、印刷キューに指定するドキュメントの名前を指定して、印刷を開始します。myPrintオブジェクトにNothingを指定してオブジェクトとの関連付けを解除します。


  Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
    Dim myPrint As New PrintDocument
    AddHandler myPrint.PrintPage, AddressOf Me.DataGrid_Print
    AddHandler myPrint.EndPrint, AddressOf Me.DataGrid_EndPrint
    myPrint.Print("DataGridGroup_Print")
    myPrint = Nothing
  End Sub

■印刷を実行する処理
新しいDataGridのインスタンス、myDataGridオブジェクトを生成します。生成したmyDataGridオブジェクトの ItemsSourceにCollectionViewSourceのインスタンスに関連付けられているビューオブジェクトを指定します。印刷する要素を指定するPageVisualプロパティにmyDataGridを指定します。
これで、画面上はスクロールしなければ表示されていないDataGridコントロールのデータすべてをXPSファイルとして出力したり、プリンターで印刷できるようになります。


  Private Sub DataGrid_Print(ByVal sender As Object, ByVal e As PrintPageEventArgs)
    Dim myDataGrid As New DataGrid
    myDataGrid.ItemsSource = myCollectionViewSource.View
    e.PageVisual = myDataGrid
    e.HasMorePages = False
  End Sub

■印刷が完了した時の処理
「完了」というメッセージボックスを表示します。


  Private Sub dataGrid_EndPrint(ByVal sender As Object, ByVal e As EndPrintEventArgs)
    MessageBox.Show("完了")
  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メルマガ会員のサービス内容を見る

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