DataGridに事前に列数および列名が不明なデータをバインドするには?

hate666komei2011-01-27


結局のところ、データベースから持ってきたDataTableのようなものをSilverlightのDataGridにセットしようとすると、複雑なやりかたをするしかなく、もっと簡単にやれないのか?と悩んでおりました。

今日、以下の記事に出会って、目からウロコがとれた気分です。

(簡単なSilverlight4のDataGridへの動的Data Binding)
http://www.go4answers.com/Example/easy-dynamic-data-binding-silverlight-4-165251.aspx

この中では、Silverlight4ではIndexを持つようなデータに対するBindingがサポートされたので、それを使えば、XMLデータに対するBindingが非常に楽になるということでした。

(indexを含むようなPropertyPathの書き方について)
http://msdn.microsoft.com/en-us/library/cc645024%28VS.95%29.aspx#indexdata

で、同じようにXMLを持ってきてやろうとしたら、同じDataTableでもXMLの中身が違うとこのコードではダメなのでした...


それで、さらによくコードを解析すると、単純にBindingの書き方だけ工夫すればよいと読めたので、世界でもっとも単純な動的Bindingのサンプルをつくりました。

1行を表すクラスは以下のものを使います。

public class DataRow {
  public Dictionary Data {get; set;}

}


あえて特殊文字入りの日本語の列名を使っています。
dataGrid1.AutoGenerateColumns = false; までがデータを作っているところなので、実際Bindingしているのはその後です。
Bindingの記述が重要です。 ポイントなので2度言いました。

var list0 = new List();
list0.Add("名称CD");
list0.Add("名称");
list0.Add("作成/-*@日");
list0.Add("予備 数値");
var rows = new System.Collections.ObjectModel.ObservableCollection();
for (int i = 0; i < 10; i++) {
var row0 = new DataRow();
row0.Data = new Dictionary();
row0.Data.Add(list0[0], "CD" + i.ToString());
row0.Data.Add(list0[1], "名称は" + i.ToString() + "です");
row0.Data.Add(list0[2], DateTime.Now);
row0.Data.Add(list0[3], i * 20 + i);
rows.Add(row0);
}
dataGrid1.AutoGenerateColumns = false;
for (int i = 0; i < 4; i++) {
var col0 = new DataGridTextColumn();
col0.Header = list0[i];
col0.Binding = new System.Windows.Data.Binding("Data[" + list0[i] + "]");
dataGrid1.Columns.Add(col0);
}
dataGrid1.ItemsSource = rows;


こういった形でBindingできることがわかると、あとは楽勝ですね。いままでなんだったのかと思うぐらい簡単でした。