C#とWPFを利用して、DataGridを使う方法をまとめてみました。
使用環境(MVVMは使いません)
・Window 11
・Visual Studio 2022
・.NET 7.0 (C# 11.0)
DataGridを利用する方法
ここでは、基礎を学ぶため、可能な限りシンプルにしたDataGridを作成します。下のような画面です。

表示する列はひとつだけ、追加、変更、削除ができるボタンはつけますが、それ以外は何もない世界。
XAMLにDataGridを定義する
まずは、XAMLを書いていきます。データを操作するためにボタンも3つつけて、その下にDataGridを定義します。
<Grid>
<DockPanel>
<StackPanel>
<Button Content="データ追加" x:Name="Button1" Click="Button1_Click" Margin="10,10,10,10"/>
<Button Content="データ変更" x:Name="Button2" Click="Button2_Click" Margin="10,10,10,10"/>
<Button Content="データ削除" x:Name="Button3" Click="Button3_Click" Margin="10,10,10,10"/>
</StackPanel>
<DataGrid x:Name="DataGrid1" AutoGenerateColumns="False" CanUserAddRows="False" Margin="10,10,10,10">
<DataGrid.Columns>
<DataGridTextColumn Header="アイテム1" Binding="{Binding Item1}" />
</DataGrid.Columns>
</DataGrid>
</DockPanel>
</Grid>
ここでの注意点は、DataGridの親になるパネルには、<StackPanel>ではなく、<DockPanel>を使うことです。
親の親も、その親も先祖代々<DockPanel>にします。
<StackPanel>でも一見うまくいったように思えますが錯覚です。行をどんどん追加していくと<StackPanel>は伸びるので、やがて画面の下端をこえて伸びてしまいます。スクロールバーも出ません。そこにあるのに見えないそんな状態になってしまいます。
データの準備
まず、DataGridの行に対応させるクラスをひとつ追加します。
public class DataGrid1Row
{
public string Item1 { get; set; } = "";
}
今回はカラムが1つなので、プロパティを1つだけ書きます。カラムが増えるとその分だけプロパティを増やしていくわけです。
そして、プロパティ名は、XAMLのマークアップ拡張、Bindingに書いた名前(バインディングソース)と同じにします。ここでは「Item1」ですね。
次に、下の画像のように、DataGridと対応させるために画面のクラス(以下「MainWindow」クラスとして説明します)にもプロパティを追加します。
行のクラスを複数束ねてObservableCollectionとしているわけです。ObservableCollectionは、値が変更されたら知らせてくれる機能がついたリストだと考えてください。
public ObservableCollection<DataGrid1Row> DataGrid1Rows { get; set; }
public MainWindow()
{
InitializeComponent();
DataGrid1Rows = new ObservableCollection<DataGrid1Row> { };
DataGrid1.ItemsSource = DataGrid1Rows;
}
そして、画面のコンストラクタの中で生成して、ItemsSourceに代入すれば準備完了です。
データの追加
そして画面のクラスに、次のメソッドを追加します。一番上のボタンをクリックすると動くロジックです。上で追加したクラスを使ってDataGridにデータを追加します。
追加された行が判別できるようにデータに連番をつけましょう。「testCounter」という変数を用意してデータに番号を加え、カウントアップしていきます。
private int testCounter = 0;
private void Button1_Click(object sender, RoutedEventArgs e)
{
DataGrid1Rows.Add(new DataGrid1Row { Item1 = $"追加データ{testCounter}" });
testCounter++;
}
これで一番上のボタンをクリックするとDataGridに行が追加されるようになります。
データの変更
さらに「MainWindow」クラスに次のメソッドを追加します。2番目のボタンがクリックされた時に動くデータを変更するロジックです。
private void Button2_Click(object sender, RoutedEventArgs e)
{
foreach (DataGrid1Row row in DataGrid1Rows)
{
row.Item1 = row.Item1.Replace("追加", "変更済");
}
DataGrid1.Items.Refresh();
}
foreachでDataGridの行を順番に処理できます。「DataGrid1Row」という型は、先ほどデータの追加のところで定義したクラスですね。
Replace()メソッドでデータの内容で「追加」となっている部分を「変更済」に置き換えます。
ここでのポイントは、最後にRefresh()メソッドを実行しておくこと。これを実行しないと反映されません。正確にいうとDataGridの値は変更されているのに、画面の表示に反映されないので、変わっていないように見えます。
なお、numberという変数は、次で説明する行の削除の際に、どの行が削除されたか分かりやすいように入れただけなので、特になくても動きます。
データの削除
最後に3番目のボタンがクリックされた時に動く、データを削除するロジック。これも「MainWindow」クラスにメソッドを追記します。
private void Button3_Click(object sender, RoutedEventArgs e)
{
if (DataGrid1Rows.Count > 0)
{
DataGrid1Rows.RemoveAt(0);
}
else
{
MessageBox.Show("削除できません。行がありません。");
}
}
クリックするたびに1行目を削除していきます。ロジックをシンプルにしてわかりやすくするために、最初の行だけを削除するようにしています。
行がない場合に削除しようとすると異常終了するので、行を削除する前に行数で判断してMessageBoxをだして回避しています。
これでとりあえず、データの追加、変更、削除といった基礎の基礎部分ができるように、なりました。
コメント