最近的一个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 / ) - (s.Width / ) ;
p.Y = cellBounds.Location.Y +
(cellBounds.Height / ) - (s.Height / );
_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[].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 = ; i < ; i++)
{
DataRow drData = _dtSource.NewRow();
drData[] = "test" + i;
drData[] = "" + i;
drData[] = "2017-05-21 10:55:21";
drData[] = "北京市";
_dtSource.Rows.Add(drData);
} dgInfo.DataSource = _dtSource; InitColumnInfo();
}
catch (Exception ex)
{ }
} private void InitColumnInfo()
{
int index = ; 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 = ; index++;
dgInfo.Columns[index].HeaderText = "身份证号";
dgInfo.Columns[index].Width = ; index++;
dgInfo.Columns[index].HeaderText = "时间";
dgInfo.Columns[index].Width = ; index++;
dgInfo.Columns[index].HeaderText = "地点";
dgInfo.Columns[index].Width = ; 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下载

C#总结(三)DataGridView增加全选列的更多相关文章

  1. Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群

    Redis总结(五)缓存雪崩和缓存穿透等问题   前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...

  2. DataGridView增加全选列

    最近的一个winform的项目中,碰到datagridview控件的第一列添加全选的功能,通常这个功能,有两种实现方式:1. 为控件添加DataGridViewCheckBoxColumn来实现,但是 ...

  3. GridControl 添加全选列

    这里通过List对象绑定GridControl,且不用在GirdControl界面中添加任何列,实现CheckBox列的方法 1.列表中出现CheckBox列 非常简单,在绑定的List实体中,增加一 ...

  4. datagridview表头全选

    参与程序http://www.codeproject.com/KB/grid/CheckBoxHeaderCell.aspx 这里老外写的一个控件,他少了委托重载的一个方法.先写一个控件 public ...

  5. 三、WPF 全选,反选,以及获取选中行

    页面代码 <TextBlock> <CheckBox Name="cbAllCreate" Click="CbAllCreate_Click" ...

  6. HTML5定制全选列头

    随着HTML5产品分支的不断深入使用,HTML5的需求也是越来越多,表格组件的使用也不例外,什么排序,分页,自动列宽等.最近有客户提出了如果让表格的列头加上全选的功能.细细分析其实就是两部分,表格的b ...

  7. easyui combobox的增加全选解决方案

      1.解决方案背景: 项目中偶然需要用到easyui的combobox的组件,但是本组件自己没有包含全选的api事件.搜索了一些解决方案,但是不是很符合,后来发现是因为所使用的版本不一致所导致的.项 ...

  8. WinForm中DataGridView的全选与取消全选

    /// <summary> /// 全选 /// </summary> private void SelectAll() { //结束列表的编辑状态,否则可能无法改变Check ...

  9. 实现DataGridView和DevExpress.GridControl表头全选功能

    1)DevExpress控件的GridView的实现多选操作 先讲DevExpress控件的GridView的实现,要实现的功能基本上是处理单击全选操作.重新绘制表头等操作,首先在加载第一步实现相关的 ...

随机推荐

  1. Python之路-基本数据类型

    一.数据类型 1.数字 包含整型和浮点型,还有复数2.字符 长度,索引,切片也适用于列表的操作 移除空白 strip() 默认字符串前后的空格,制表符,换行符 strip(";") ...

  2. 转接口IC GM7122:BT656转CVBS芯片 视频编码电路

    1 概述    视频编码电路主要实现接收8位CCIR656格式的YUV数据,(例如MPEG解码数据),并编码成CVBS信号,经过D/A转换后输出.基本的编码功能包括副载波产生,色差信号调制,同步信号内 ...

  3. (iOS)关于zbar扫描条形码,所搭载的设备

    四个月之前写的,现在发出来. 最近在开发一款程序的时候,功能要求扫描条形码. 现在最流行的扫描条形码的开源代码有zbar和zxing两种,可以支持多种一维和二维码. 之前了解过zbar,所以这次试用z ...

  4. Eclipse中Maven插件部分常用功能命令介绍

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6689010.html Eclipse中安装Maven插件之后,就能很方便的管理Maven项 ...

  5. C#基础语法(一)

    一.基础语法 1.C#区分大小写,所以myVar和MyVar是两个不同的变量. 2.每个C#可执行文件(如控制台应用程序,Windows应用程序和Windows服务)都必须有一个入口点----Main ...

  6. spring mvc mybatis集成踩的坑

    开园这么多年了也没写几篇文章,现在想想光看别人的也不行啊,咱也自己写写,就写这天我我在做spring mvc与mybatis的集成时遇到的问题 1 spring与mybatis的集成 这个相信大家都弄 ...

  7. ROS使用常见问题

    1.Q:查看ros版本 A:先在终端输入roscore,打开新终端,再输入,rosparam list,再输入rosparam get /rosdistro,就能得到版本. 2.Q:运行命令$ ros ...

  8. JS数组根据属性来实现排序

    var data = [{ name: "zhao", age: }, { name: "qian", age: }, { name: "sun&qu ...

  9. CSS样式表初学,比C#和JS简单

    今天咱们一起来看下CSS样式表的基本基础 经常看博客或者喜欢钻研代码这一类的人对CSS可能有所耳闻,但具体的可能不是很清楚 那什么是CSS呢?与HTML又有什么区别呢?今天咱们就来说道下这个CSS C ...

  10. 关于mysql查询区分大小写

    使用查询语句时,携带collate utf8_bin 在SQL语句中使用collate 使用collate子句,能够为一个比较覆盖任何默认校对规则.collate可以用于多种SQL语句中,比如wher ...