DataGridView增加全选列
最近的一个winform的项目中,碰到datagridview控件的第一列添加全选的功能,通常这个功能,有两种实现方式:1. 为控件添加DataGridViewCheckBoxColumn来实现,但是需要提供全选反选功能,2. 再加一个checkbox控件跟datagridview组合来实现全选反选功能。但是,感觉这两种实现效果都不是很好。网上查资料,发现一个老外的实现方法,比较简单通用。demo 代码最下面的连接给出。
他的实现方式就是:DataGridViewCheckBoxColumn的父类DataGridViewColumnHeaderCell 里面有个HeaderCell的属性,看下DataGridViewColumnHeaderCell 的继承关系,就可以知道它继承自DataGridViewCell类, 所以只需要重写DataGridViewColumnHeaderCell类的paint方法,用CheckBoxRenderer画一个Checkbox到单元格上。即可实现在datagridview的列头增加一个全选的checkbox 。以下是实现代码:
实现代码

public delegate void CheckBoxClickedHandler(bool state);
public class DataGridViewCheckBoxHeaderCellEventArgs : EventArgs
{
bool _bChecked;
public DataGridViewCheckBoxHeaderCellEventArgs(bool bChecked)
{
_bChecked = bChecked;
}
public bool Checked
{
get { return _bChecked; }
}
}
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()
{
} 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);
}
}

调用方式
DataGridViewCheckBoxColumn colCB = new DataGridViewCheckBoxColumn();
DatagridViewCheckBoxHeaderCell cbHeader = new DatagridViewCheckBoxHeaderCell();
colCB.HeaderCell = cbHeader;
datagridview1.Columns.Add(colCB);
cbHeader.OnCheckBoxClicked +=
new CheckBoxClickedHandler(cbHeader_OnCheckBoxClicked);
1. 我们只需要定义一个DataGridViewCheckBoxColumn。
2. 然后为每一行的checkbox 定义一个CheckboxClicked 事件。
测试程序
创建一个Winform 项目,加个datagridview控件,初始化几行默认数据。注意:datagirdview有编辑状态,如果有一行数据在编辑状态,那这一行被编辑。
解决办法就是在事件的绑定方法里面增加EndEdit()调用。

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent(); InitDtSource();
} private void cbHeader_OnCheckBoxClicked(bool state)
{
//这一句很重要结束编辑状态
dgInfo.EndEdit();
dgInfo.Rows.OfType<DataGridViewRow>().ToList().ForEach(t => t.Cells[0].Value = state);
} private void InitDtSource()
{
try
{
var _dtSource = new DataTable();
//1、添加列
_dtSource.Columns.Add("姓名", typeof(string)); //数据类型为 文本
_dtSource.Columns.Add("身份证号", typeof(string)); //数据类型为 文本
_dtSource.Columns.Add("时间", typeof(string)); //数据类型为 文本
_dtSource.Columns.Add("地点", typeof(string)); //数据类型为 文本 for (int i = 0; i < 10; i++)
{
DataRow drData = _dtSource.NewRow();
drData[0] = "test" + i;
drData[1] = "35412549554521263" + i;
drData[2] = "2017-05-21 10:55:21";
drData[3] = "北京市";
_dtSource.Rows.Add(drData);
} dgInfo.DataSource = _dtSource; InitColumnInfo();
}
catch (Exception ex)
{ }
} private void InitColumnInfo()
{
int index = 0; DataGridViewCheckBoxColumn colCB = new DataGridViewCheckBoxColumn();
DatagridViewCheckBoxHeaderCell cbHeader = new DatagridViewCheckBoxHeaderCell();
colCB.HeaderCell = cbHeader;
colCB.HeaderText = "全选";
cbHeader.OnCheckBoxClicked += new CheckBoxClickedHandler(cbHeader_OnCheckBoxClicked);
dgInfo.Columns.Insert(index, colCB); index++;
dgInfo.Columns[index].HeaderText = "姓名";
dgInfo.Columns[index].Width = 90; index++;
dgInfo.Columns[index].HeaderText = "身份证号";
dgInfo.Columns[index].Width = 120; index++;
dgInfo.Columns[index].HeaderText = "时间";
dgInfo.Columns[index].Width = 150; index++;
dgInfo.Columns[index].HeaderText = "地点";
dgInfo.Columns[index].Width = 100; System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;//211, 223, 240
dataGridViewCellStyle2.ForeColor = System.Drawing.Color.Blue;
dataGridViewCellStyle2.SelectionForeColor = System.Drawing.Color.Blue;
dgInfo.Columns[index].DefaultCellStyle = dataGridViewCellStyle2;
}
}

其他
1. 参考地址:https://www.codeproject.com/Articles/20165/CheckBox-Header-Column-For-DataGridView
2. Demo下载
转自-https://www.cnblogs.com/zhangweizhong/p/6885507.html
DataGridView增加全选列的更多相关文章
- Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群
Redis总结(五)缓存雪崩和缓存穿透等问题 前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...
- C#总结(三)DataGridView增加全选列
最近的一个winform的项目中,碰到datagridview控件的第一列添加全选的功能,通常这个功能,有两种实现方式:1. 为控件添加DataGridViewCheckBoxColumn来实现,但是 ...
- GridControl 添加全选列
这里通过List对象绑定GridControl,且不用在GirdControl界面中添加任何列,实现CheckBox列的方法 1.列表中出现CheckBox列 非常简单,在绑定的List实体中,增加一 ...
- datagridview表头全选
参与程序http://www.codeproject.com/KB/grid/CheckBoxHeaderCell.aspx 这里老外写的一个控件,他少了委托重载的一个方法.先写一个控件 public ...
- HTML5定制全选列头
随着HTML5产品分支的不断深入使用,HTML5的需求也是越来越多,表格组件的使用也不例外,什么排序,分页,自动列宽等.最近有客户提出了如果让表格的列头加上全选的功能.细细分析其实就是两部分,表格的b ...
- easyui combobox的增加全选解决方案
1.解决方案背景: 项目中偶然需要用到easyui的combobox的组件,但是本组件自己没有包含全选的api事件.搜索了一些解决方案,但是不是很符合,后来发现是因为所使用的版本不一致所导致的.项 ...
- WinForm中DataGridView的全选与取消全选
/// <summary> /// 全选 /// </summary> private void SelectAll() { //结束列表的编辑状态,否则可能无法改变Check ...
- 实现DataGridView和DevExpress.GridControl表头全选功能
1)DevExpress控件的GridView的实现多选操作 先讲DevExpress控件的GridView的实现,要实现的功能基本上是处理单击全选操作.重新绘制表头等操作,首先在加载第一步实现相关的 ...
- C# winform中的datagridview控件标头加入checkbox,实现全选功能。
/// <summary> /// 给DataGridView添加全选 /// </summary> public class AddCheckBoxToDataGridVie ...
随机推荐
- Azure上批量创建OS Disk大于30G的Linux VM
Azure上VM的OS盘的大小在创建时是固定的.Windows是127G,Linux是30G.如果需要批量创建的VM的OS Disk有更大的容量.可以考虑用下面的方法实现. 1 创建一台有Data-d ...
- 推荐几个MySQL大牛的博客
1.淘宝丁奇 http://dinglin.iteye.com/ 2.周振兴@淘宝 花名:苏普 http://www.orczhou.com/ 3. 阿里云数据库高级专家彭立勋为 MariaDB Fo ...
- canvas渐变
代码: 1 /** 2 * Created by Administrator on 2016/1/29. 3 */ 4 function draw(id){ 5 var canvas = docume ...
- maven 学习 十 关于打包
clean package -Dmaven.test.skip=true -P product 这个命令干的活: 清class文件,打包构建,跳过测试,注意最后一个 -P product, 会激活项目 ...
- linq to sql 类的使用
本文介绍linq to sql模型类的使用 EntityFramework是重量级的数据库模型,如果你想要一个简单轻量级的数据库模型,建议使用linq to sql类 创建模型类 在项目中添加linq ...
- C获取当前时间
#include <stdio.h> #include <time.h> #include <string> #include <windows.h> ...
- appium如何连接模拟器代码实例
from appium import webdriver def connect(self): self.desired_caps = {} self.desired_caps['platformNa ...
- JAVA基础知识总结8(设计模式)
设计模式:JAVA中有23种设计模式 1.解决问题最行之有效的思想. 2.是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 3.使用设计模式是为了可重用代码.让代码更容易被他人理解 ...
- js中的操作符
写在前面 js语法 DOM对象(把body,div,p等节点树看成一个对象) BOM对象(把浏览器的地址栏历史记录DOM等装在一个对象) 浏览器是宿主,但js的宿主不限于浏览器,也可以是服务器,如no ...
- SQLiteopenhelper创建database的过程
首先由于SQLiteOpenHelper是一个抽象类,所以我们要创建一个自己的类实现它,并实现抽象方法, public void onCreate(SQLiteDatabase db) public ...