WinForm实现DataGridView表头复选框全选功能
运行效果

实现思路
要实现DataGridView表头复选框全选功能,我们需要以下几个步骤:
- 创建自定义表头单元格类:继承自
DataGridViewColumnHeaderCell,重写Paint方法绘制复选框 - 处理鼠标点击事件:在表头单元格中检测鼠标点击位置,判断是否点击了复选框
- 实现状态切换:点击复选框时切换选中状态,并触发事件通知父组件
- 添加事件处理:在主表单中订阅事件,实现全选/全不选逻辑
核心代码解析
1. 自定义表头单元格类
首先,我们需要创建一个自定义的表头单元格类,用于绘制复选框并处理点击事件:
public class DatagridViewCheckBoxHeaderCell : DataGridViewColumnHeaderCell
{
Point checkBoxLocation;
Size checkBoxSize;
bool _checked = false;
Point _cellLocation = new Point();
System.Windows.Forms.VisualStyles.CheckBoxState _cbState =
System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal;
public event CheckBoxClickedHandler OnCheckBoxClicked;
// 构造函数
public DatagridViewCheckBoxHeaderCell()
{
}
// 重写Paint方法绘制复选框
protected override void Paint(System.Drawing.Graphics graphics,
System.Drawing.Rectangle clipBounds,
System.Drawing.Rectangle cellBounds,
int rowIndex,
DataGridViewElementStates dataGridViewElementState,
object value,
object formattedValue,
string errorText,
DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
DataGridViewPaintParts paintParts)
{
// 调用基类方法绘制基本内容
base.Paint(graphics, clipBounds, cellBounds, rowIndex,
dataGridViewElementState, value,
formattedValue, errorText, cellStyle,
advancedBorderStyle, paintParts);
// 计算复选框位置和大小
Point p = new Point();
Size s = CheckBoxRenderer.GetGlyphSize(graphics,
System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);
p.X = cellBounds.Location.X +
(cellBounds.Width / 2) - (s.Width / 2);
p.Y = cellBounds.Location.Y +
(cellBounds.Height / 2) - (s.Height / 2);
_cellLocation = cellBounds.Location;
checkBoxLocation = p;
checkBoxSize = s;
// 根据选中状态设置复选框样式
if (_checked)
_cbState = System.Windows.Forms.VisualStyles.
CheckBoxState.CheckedNormal;
else
_cbState = System.Windows.Forms.VisualStyles.
CheckBoxState.UncheckedNormal;
// 绘制复选框
CheckBoxRenderer.DrawCheckBox
(graphics, checkBoxLocation, _cbState);
}
// 处理鼠标点击事件
protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
{
// 计算点击位置
Point p = new Point(e.X + _cellLocation.X, e.Y + _cellLocation.Y);
// 判断是否点击了复选框
if (p.X >= checkBoxLocation.X && p.X <=
checkBoxLocation.X + checkBoxSize.Width
&& p.Y >= checkBoxLocation.Y && p.Y <=
checkBoxLocation.Y + checkBoxSize.Height)
{
// 切换选中状态
_checked = !_checked;
// 触发事件
if (OnCheckBoxClicked != null)
{
OnCheckBoxClicked(_checked);
this.DataGridView.InvalidateCell(this);
}
}
base.OnMouseClick(e);
}
}
2. 事件委托定义
为了在表头复选框状态改变时通知父组件,我们需要定义一个事件委托:
public delegate void CheckBoxClickedHandler(bool state);
3. 实现全选/全不选逻辑
在主表单中,我们需要订阅表头复选框的点击事件,并实现全选/全不选逻辑:
private void HeaderCheckBoxClicked(bool state)
{
//这一句很重要结束编辑状态,否则处于编辑状态的勾选框是不会被改变的
dataGridView1.EndEdit();
dataGridView1.Rows.OfType<DataGridViewRow>().ToList().ForEach(t => t.Cells[0].Value = state);
}
使用方法
1. 添加自定义类
将上述DatagridViewCheckBoxHeaderCell类和CheckBoxClickedHandler委托添加到你的项目中。
2. 创建DataGridView并设置列
在表单中添加DataGridView控件,然后在代码中初始化:
private void InitializeDataGridView()
{
// 创建复选框列
DataGridViewCheckBoxColumn checkBoxColumn = new DataGridViewCheckBoxColumn();
checkBoxColumn.HeaderText = "选择";
checkBoxColumn.Width = 80;
// 设置自定义表头单元格
DatagridViewCheckBoxHeaderCell headerCell = new DatagridViewCheckBoxHeaderCell();
headerCell.OnCheckBoxClicked += new CheckBoxClickedHandler(HeaderCheckBoxClicked);
checkBoxColumn.HeaderCell = headerCell;
// 添加其他列
dataGridView1.Columns.Add(checkBoxColumn);
dataGridView1.Columns.Add("Name", "姓名");
dataGridView1.Columns.Add("Age", "年龄");
dataGridView1.Columns.Add("Gender", "性别");
// 添加示例数据
dataGridView1.Rows.Add(false, "张三", 20, "男");
dataGridView1.Rows.Add(false, "李四", 21, "女");
dataGridView1.Rows.Add(false, "王五", 22, "男");
dataGridView1.Rows.Add(false, "赵六", 23, "女");
dataGridView1.Rows.Add(false, "孙七", 24, "男");
}
3. 订阅事件
在表单构造函数中调用初始化方法,并确保事件能够正确触发:
public Form1()
{
InitializeComponent();
InitializeDataGridView();
}

浙公网安备 33010602011771号