きよくらの備忘録

「三日坊主と呼ばせない!日記」改め。主にソフトウェア開発関連の話題。

WPF:DataGridにList<Dictionary<string, object>>をbindする

前回ポストの Dapperの結果のDapperRowのコレクションを単純なDictionaryのコレクションに変換する - きよくらの備忘録 に関連して。

List<Dictionary<string, object>>の形のデータをWPFのDataGridにバインドするのに少し手間取ったので備忘録として。

XAMLでDataGridTextColumnを定義する場合

XAML:

<DataGrid x:Name="DataGrid" AutoGenerateColumns="False">
  <DataGrid.Columns>
    <DataGridTextColumn Header="ID" Binding="{Binding Item[ID]}" />
    <DataGridTextColumn Header="Name" Binding="{Binding Item[Name]}" />
    <DataGridTextColumn Header="ID" Binding="{Binding Item[BirthDay]}" />
  </DataGrid.Columns>
</DataGrid>

C#コード:

public MainWindow()
{
  InitializeComponent();

  var list = new List<Dictionary<string, object>>
  {
    new Dictionary<string, object>() {{"ID", 1}, {"Name", "Taro"}, {"BirthDay",new DateTime(2001,10,1)}},
    new Dictionary<string, object>() {{"ID", 2}, {"Name", "Jiro"}, {"BirthDay",new DateTime(2004,2,3)}},
    new Dictionary<string, object>() {{"ID", 3}, {"Name", "Saburo"}, {"BirthDay",new DateTime(2010,5,21)}}
  };

  DataGrid.ItemsSource = list;
}

実行結果例:

動的にDataGridTextColumnを定義する場合

前回の例のようにKeyを事前にXAMLに記述決定できないような場合はDataGridTextColumn を動的に生成すればOK

XAML:

<DataGrid x:Name="DataGrid" AutoGenerateColumns="False">
  <DataGrid.Columns />
</DataGrid>

C#コード:

public MainWindow()
{
  InitializeComponent();

  var list = new List<Dictionary<string, object>>
  {
    new Dictionary<string, object>() {{"ID", 1}, {"Name", "Taro"}, {"BirthDay",new DateTime(2001,10,1)}},
    new Dictionary<string, object>() {{"ID", 2}, {"Name", "Jiro"}, {"BirthDay",new DateTime(2004,2,3)}},
    new Dictionary<string, object>() {{"ID", 3}, {"Name", "Saburo"}, {"BirthDay",new DateTime(2010,5,21)}}
  };

  // 1行目のKeysから取得したKeyで列をカラムを生成
  foreach (var key in list[0].Keys)
  {
    DataGrid.Columns.Add(new DataGridTextColumn()
    {
      Header = key,
      Binding = new Binding($"Item[{key}]")
    });
  }

  DataGrid.ItemsSource = list;
}