DataGridに事前に列数および列名が不明なデータをバインドするには?
結局のところ、データベースから持ってきた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 DictionaryData {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できることがわかると、あとは楽勝ですね。いままでなんだったのかと思うぐらい簡単でした。