DataGridの内容を動的に変更する。

SilverlightのDataGridコントロール。データを表形式で表示できる便利な代物だが、SilverlightにDataSetが無いせいでデータの渡し方が大分限定的になっている。


たぶん一般的な利用方法はクラスのコレクションをItemSourceプロパティに設定する方法だろう。


[VB.NET]
  Dim data1List As New List(Of Data1)
  data1List.Add(New Data1("prop1-1","prop2-1")
  data1List.Add(New Data1("prop1-2","prop2-2")
  dataGrid1.ItemSource = data1List


  Private Class Data1
    Public Sub New(prop1 As String, prop2 As String)
     Property1 = prop1
     Property2 = prop2
    End Sub


    Public Property Property1 As String
    End Property


    Public Property Property2 As String
    End Property
  End Class


上記の実装だと、"Property1"と"Property2"の列が自動的に生成されて、リストにAddした2つのデータが行としてDataGrid差し込まれる。プロパティ名を自動的に取得して表にしてくれるのはわかりやすくていい機能だと思う。


問題は表を自作したい場合。上記の方法は事前にクラスを用意しなければならない。自分で列を用意して、それに応じたデータも自分で定義したい。WindowsFormやASP.NETならDataSetクラスがあったのでそれを使えたのだが、Silverlight3の段階ではそのクラスは使えない。


DataGridでは列の追加は出来る。しかし、行の情報はItemSourceに定義されたデータからバインドするため、行の追加はItemSourceに渡すデータで管理する。
つまり、列追加をDataGridで、行追加を上記のコードで言うならdata1Listでやればそれでいい。

ただ、この方法は、下記の様に配列やListを使って表を作成したい場合、こちらとしては、ネスト内のListが1行として横に文字列が並んでほしいが、実際はListクラスのプロパティの内容が並ぶだけである。


[VB.NET]
  Dim dynamicDataList As New List(Of List(Of String))


そのため、バインドの定義もこちらで用意しなければならない。Collectionを使ってバインディングをしたい場合、プロパティに"SyncRoot"を指定する。どうやらこの中にデータが入っているようだ。


だらだら長くなったが、以下の実装によって一応動的にDataGridによる表を作成することができる。



[VB.NET]
  Dim dataColumn1 As New DataGridTextColumn
  dataColumn1.Header = "Column1"
  dataColumn1.Bind = New System.Windows.Data.Binding("SyncRoot[0]")
  dataGrid1.Columns.Add(dataColumn1)


  Dim dataColumn2 As New DataGridTextColumn
  dataColumn2.Header = "Column2"
  dataColumn2.Bind = New System.Windows.Data.Binding("SyncRoot[0]")
  dataGrid1.Columns.Add(dataColumn2)


  Dim data1List As New List(Of List(Of String))


  Dim data1Row1 As List(Of String)
  Data1Row1.Add("col1row1")
  Data1Row1.Add("col2row1")
  data1List.Add(Data1Row1)


  Dim data1Row2 As List(Of String)
  Data1Row1.Add("col1row2")
  Data1Row1.Add("col2row2")
  data1List.Add(Data1Row2)


  dataGrid1.ItemSource = data1List


てか、まぁ、、、DataSetが導入されればこんなめんどい実装はたぶんなくなる(希望)。