PR

【C# WPF】DataGridでCheckBoxを使う方法

C#

C#とWPFを利用して、DataGridでCheckBoxを使う方法をまとめてみました。

対象は、Visual Studio 2022, .NET 7.0, Windows 7以上 です。
MVVMは使いません。Windows Formsではありません。

スポンサーリンク

全体像

前回作ったDataGridにチェックボックスを加えてみます。
ヘッダーのチェックボックスをクリックすると、全ての明細行のチェックボックスが連動してオンオフします。
よく見かける仕様かなと思います。

次のような画面になります。

画面に追加するのはヘッダーと明細行のチェックボックスだけです。
それ以外の部分は別の記事「【C# WPF】DataGridの使い方の基礎」で説明したものです。不明な点があれば参照してみてください。

XAMLの記入

DataGridCheckBoxColumn というタグが用意されていますが、コードが複雑になるので使いません。
代わりに、DataGridTemplateColumn を使います。

MainWindow.xaml

最初に、CheckBoxを配置する列の全体を DataGridTemplateColumn タグで囲みます。
その中にヘッダーと明細行を定義していきます。
ヘッダー部分は、DataGridTemplateColumn.Header を書いて、その中に CheckBox を書きます。
明細行の部分は、DataGridTemplateColumn.CellTemplate 書いて、その中に DataTemplate を書き、その中に CheckBox を書きます。

チェックボックスが、クリックされる度にチェックがオンになったり、オフになったりしますが、この
ヘッダーと明細行で若干違います。

ヘッダーは、チェックボックスがオンになっているのか、オフになっているのかを値として伝えることができません。

代わりに、オンにする時とオンにした時のイベントを別々にすることで対応します。なので、イベントが2つになるわけですね。「Checked=~~」と「Unchecked=~~」の部分です。

明細行は、チェックボックスがオンになっているのか、オフになっているのかを値として伝えます。

CheckBox用のプロパティを準備

まず、DataGridのカラムに対応させたクラスに、チェックボックスのプロパティを追加します。

明細行のチェックがオンならtrue、オフならfalseとなるbool型の項目です。

MainWindow.xaml.cs

プロパティ名は、XAMLのマークアップ拡張、Bindingに書いた名前(バインディングソース)と同じにします。ここでは「ItemCheckBox」ですね。

行の追加の処理

プロパティは明細行のチェックボックスのオンオフの値を扱います。bool型でチェックボックがオンならtrue、オフならfalseです。

そして、データ追加の処理に「ItemCheckBox」を追記しておきます。

MainWindow.xaml.cs

ヘッダーのチェック オン/オフに対応した処理

ヘッダーの方は、前に述べた通り値を扱えないのでプロパティの記載はありません。
代わりに発生するイベントに対応した処理を追加します。

MainWindow.xaml.cs

ヘッダーのチェックボックスをオンにした時のイベントは、foreach で明細行をすべて処理して、trueをセットしていきます。
ヘッダーのチェックボックスをオンにした時のイベントは、ほぼ同じで、セットする内容がfalseになるだけですね

両方ともRefresh()を忘れると画面表示に反映されないので注意です。

ヘッダーのチェックボックスの場合は、明細のテキストボックスを編集中にクリックすると、Refresh()でエラーになります。

そこで、エラーを避けるため、Refresh()を実行する前にCommitEdit()とCancelEdit()を実行しておきます。CommitEdit()は今まで編集した行の編集内容を反映させるメソッド。CancelEdit()は編集モードを終了させるメソッドです。

まとめ

つぎの2点に気をつければ、DataGridの中でCheckBoxを使えるようになります。

  • XAMLでは、チェックボックスを定義するとき DataGridCheckBoxColumn を使うより、DataGridTemplateColumn の中に CheckBox を書く方が便利
  • ヘッダーと明細行では、チェックボックスのオン/オフに対応する方法が違う
  • ヘッダーの場合、Refresh()の前にCommitEdit()とCancelEdit()を実行しておかないとエラーになるケースがある

コメント

スポンサーリンク
タイトルとURLをコピーしました