はじめに
WinFormsのDataGridViewで、選択セルだけ背景色を変えたい場合があります。
このとき、選択行全体は色を変えず、列やセルの状態に応じて色を変えたいという要望に応える実装例をまとめます。
実装したい内容の整理
- DataGridViewで選択されたセルだけ背景色を変更
- 選択行全体は変更せず、セル単位で制御
- 列名やセルの値、ReadOnly状態に応じて色を変えたい
実装方法
0. セル単位で選択できるようにする
まず、DataGridView の選択モードを「行選択」から「セル選択」に変更します。
// フォームロード時などに設定
dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
1. CellPaintingイベントを使う
セルが描画される直前に呼ばれる CellPainting イベントを利用します。
これにより、選択セルだけを上書き描画できます。
2. CurrentCellの判定で対象セルを限定
private void DataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
// ヘッダー行や列ヘッダーは対象外
if (e.RowIndex < 0 || e.ColumnIndex < 0)
return;
DataGridView dgv = (DataGridView)sender;
var current = dgv.CurrentCell;
// 現在選択されているセルのみ処理
if (current != null && e.RowIndex == current.RowIndex && e.ColumnIndex == current.ColumnIndex)
{
e.Handled = true; // 既定の描画をキャンセル
// 条件に応じた色の指定
var cell = dgv[e.ColumnIndex, e.RowIndex];
bool isReadOnly = cell.ReadOnly;
Color highlightColor = GetCellHighlightColor(isReadOnly);
// セル背景を塗りつぶす
using (Brush brush = new SolidBrush(highlightColor))
{
e.Graphics.FillRectangle(brush, e.CellBounds);
}
// セル内容(文字など)を描画
e.PaintContent(e.CellBounds);
// 枠線を描画(右下が消えないようにする)
e.Paint(e.CellBounds, DataGridViewPaintParts.Border);
return;
}
}
3. 色決定関数例
セルがReadOnlyかどうかで色を変えたり、列名や値に応じて条件分岐も可能です。
private Color GetCellHighlightColor(bool isReadOnly)
{
if (isReadOnly)
return Color.LightGray; // 編集不可セルはグレー
else
return Color.Yellow; // 編集可能セルは黄色
}
値や列名で分岐する例:
private Color GetCellHighlightColor(string columnName, object cellValue)
{
if (columnName == "列名1") return Color.Yellow;
if (cellValue?.ToString() == "特定値") return Color.LightGreen;
return Color.White;
}
CurrentCellChangedではダメ
CurrentCellChangedで色を変えようとすると、画面の再描画順序によってSelectionBackColorが優先され、セルの色変更が反映されない
ポイントまとめ
- 「セル単位での条件付き色付け」には
CellPainting -
CurrentCellで選択セルを判定 - 枠線は自前で描画する
- ReadOnlyや値・列名に応じて色を変えられる