2011年3月11日金曜日

列のヘッダーに、すべて選択用のチェックボックスを配置する

DataGridViewにチェックボックス列を用意した場合、どうせならすべて選択用のチェックボックスも用意したいところです。
列のヘッダーにチェックボックスを配置するには、以下の実装を行います。

  1. すべて選択用のチェックボックスを用意する。
    (例えば、Formの任意の位置に配置し、VisibleプロパティをFalseにします。)
  2. DataGridViewのCellPaintingイベントで、列ヘッダーにチェックボックスを描画する。
  3. DataGridViewのCellClickイベントで、列ヘッダーのチェックボックスの押下イベントを擬似的に取得する。
  4. CheckBoxのCheckChangedイベントで、すべての行のチェック状態を切り替える。
【実行例】

// すべて選択用のチェックボックスを用意
private CheckBox checkBoxAll = new System.Windows.Forms.CheckBox();

// 列ヘッダーにチェックボックスを表示
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    // 列ヘッダーのみ処理を行う。(CheckBox配置列が先頭列の場合)
    if (e.ColumnIndex == 0 && e.RowIndex == -1)
    {
        using (Bitmap bmp = new Bitmap(100, 100))
        {
            // チェックボックスの描画領域を確保
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.Clear(Color.Transparent);
            }

            // 描画領域の中央に配置
            Point pt1 = new Point((bmp.Width - checkBoxAll.Width) / 2, (bmp.Height - checkBoxAll.Height) / 2);
            if (pt1.X < 0) pt1.X = 0;
            if (pt1.Y < 0) pt1.Y = 0;

            // Bitmapに描画
            checkBoxAll.DrawToBitmap(bmp, new Rectangle(pt1.X, pt1.Y, bmp.Width, bmp.Height));

            // DataGridViewの現在描画中のセルの中央に描画
            int x = (e.CellBounds.Width - bmp.Width) / 2;
            int y = (e.CellBounds.Height - bmp.Height) / 2;

            Point pt2 = new Point(e.CellBounds.Left + x, e.CellBounds.Top + y);

            e.Paint(e.ClipBounds, e.PaintParts);
            e.Graphics.DrawImage(bmp, pt2);
            e.Handled = true;
        }
    }
}

// 列ヘッダーのチェックボックスを押したときに、すべて選択用のチェックボックス状態を切り替え
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == 0 && e.RowIndex == -1)
    {
        checkBoxAll.Checked = !checkBoxAll.Checked;
    }
}

// すべての行のチェック状態を切り替える
private void checkBoxAll_CheckedChanged(object sender, EventArgs e)
{
    foreach (DataGridViewRow row in this.dataGridView1.Rows)
    {
        row.Cells[0].Value = checkBoxAll.Checked;
    }
}

0 コメント:

コメントを投稿