在DataGridView中实现Checkbox的全选的方法就是在列头画一个checkbox, 并给其一个事件.

这个之前很多blog都有写, 这里就不多废话了,  codeproject上面有示例代码.

这里我们再多做一层的封装,将其封装成一个控件,这样的话, 我们就可以最大程度上的复用, 而不需要老是重复写同样的, 无聊的代码了!

思路如下:

继承DataGridViewCheckBoxColumn类, 更改它的headerCell的样式. 添加cellValueChanged时间,使在进行复选框选择的时候可以触发事件,从而进行处理.

继承DataGridViewColumnHeaderCell类, 重新绘制一个带CheckBox的HeaderCell

话不多说直接上代码了, 如果有不懂的欢迎留言:

public class DataGridViewCheckBoxColumnSelectAll : DataGridViewCheckBoxColumn
{
private DatagridViewCheckBoxHeaderCell headerCell;
private bool loaded; public event CheckBoxClickedHandler OnCheckBoxClicked;
int TotalCheckedCheckBoxes = ;
bool IsHeaderCheckBoxClicked = false; public DataGridViewCheckBoxColumnSelectAll()
{
this.headerCell = new DatagridViewCheckBoxHeaderCell();
base.HeaderCell = this.headerCell; this.headerCell.OnCheckBoxClicked += new CheckBoxClickedHandler(this.headerCell_OnCheckBoxClicked);
this.loaded = false; } public DataGridViewCheckBoxColumnSelectAll(bool threeState)
: base(threeState)
{
this.headerCell = new DatagridViewCheckBoxHeaderCell();
base.HeaderCell = this.headerCell;
} /// <summary>
/// 在DataGridView改变时进行事件的绑定
/// </summary>
protected override void OnDataGridViewChanged()
{
if (this.DataGridView!=null)
{
this.DataGridView.CellValueChanged -= DataGridView_CellValueChanged;
this.DataGridView.CellValueChanged += DataGridView_CellValueChanged;
this.DataGridView.CurrentCellDirtyStateChanged -= DataGridView_CurrentCellDirtyStateChanged;
this.DataGridView.CurrentCellDirtyStateChanged += DataGridView_CurrentCellDirtyStateChanged;
}
} /// <summary>
/// 在复选的时候进行判断.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void DataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex>=&&e.ColumnIndex>=)
{
if (!IsHeaderCheckBoxClicked)
RowCheckBoxClick((DataGridViewCheckBoxCell)this.DataGridView[e.ColumnIndex, e.RowIndex]);
} } /// <summary>
/// 在复选框被选中的时候触发该事件, 该事件用于触发ValueChanged事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DataGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (this.DataGridView.CurrentCell is DataGridViewCheckBoxCell)
this.DataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
} /// <summary>
/// 复选框被点击时所需要做的操作
/// </summary>
/// <param name="checkBox"></param>
private void RowCheckBoxClick(DataGridViewCheckBoxCell checkBox)
{
var head = this.headerCell as DatagridViewCheckBoxHeaderCell;
if (checkBox != null)
{
//计算所有被选中的行的数量
if ((bool)checkBox.Value && TotalCheckedCheckBoxes < this.DataGridView.RowCount)
TotalCheckedCheckBoxes++;
else if (TotalCheckedCheckBoxes > )
TotalCheckedCheckBoxes--; //当所有复选框都被选中的时候,列的头上的复选框被选中, 反之则不被选中.
if (TotalCheckedCheckBoxes < this.DataGridView.RowCount)
head.IsChecked = false;
else if (TotalCheckedCheckBoxes == this.DataGridView.RowCount)
head.IsChecked = true;
//强制repained
head.DataGridView.InvalidateCell(head);
}
} /// <summary>
/// 头被选中时触发OnCheckBoxClicked事件.
/// </summary>
/// <param name="state"></param>
private void headerCell_OnCheckBoxClicked(bool state)
{
if (this.OnCheckBoxClicked != null)
{
this.OnCheckBoxClicked(state);
}
} }
 public delegate void CheckBoxClickedHandler(bool state);

    internal class DatagridViewCheckBoxHeaderCell : DataGridViewColumnHeaderCell
{
private CheckBoxState _cbState = CheckBoxState.UncheckedNormal;
private Point _cellLocation = new Point();
private bool _checked;
private Point checkBoxLocation;
private Size checkBoxSize; public bool IsChecked
{
get
{
return _checked;
} set
{
_checked = value;
if (this._checked)
{
this._cbState = CheckBoxState.CheckedNormal;
}
else
{
this._cbState = CheckBoxState.UncheckedNormal;
}
}
} public event CheckBoxClickedHandler OnCheckBoxClicked; /// <summary>
/// 点击列头的时候触发的事件,这里有个判断, 如果点击的位置是复选框则触发OnCheckBoxClicked事件.
/// </summary>
/// <param name="e"></param>
protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
{
Point point = new Point(e.X + this._cellLocation.X, e.Y + this._cellLocation.Y);
if (((point.X >= this.checkBoxLocation.X) && (point.X <= (this.checkBoxLocation.X + this.checkBoxSize.Width))) && ((point.Y >= this.checkBoxLocation.Y) && (point.Y <= (this.checkBoxLocation.Y + this.checkBoxSize.Height))))
{
this._checked = !this._checked;
bool temp = this._checked;
if (this.OnCheckBoxClicked != null)
{
this.OnCheckBoxClicked(this._checked);
base.DataGridView.InvalidateCell(this);
}
foreach (DataGridViewRow row in base.DataGridView.Rows)
{
((DataGridViewCheckBoxCell)row.Cells[e.ColumnIndex]).Value = temp;
}
base.DataGridView.RefreshEdit(); }
base.OnMouseClick(e);
} /// <summary>
/// 绘制一个CheckBox
/// </summary>
protected override void Paint(Graphics graphics, Rectangle clipBounds, 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 point = new Point();
Size glyphSize = CheckBoxRenderer.GetGlyphSize(graphics, CheckBoxState.UncheckedNormal);
point.X = (cellBounds.Location.X + (cellBounds.Width / 2)) - (glyphSize.Width / 2);
point.Y = (cellBounds.Location.Y + (cellBounds.Height / 2)) - (glyphSize.Height / 2);
this._cellLocation = cellBounds.Location;
this.checkBoxLocation = point;
this.checkBoxSize = glyphSize;
if (this._checked)
{
this._cbState = CheckBoxState.CheckedNormal;
}
else
{
this._cbState = CheckBoxState.UncheckedNormal;
}
CheckBoxRenderer.DrawCheckBox(graphics, this.checkBoxLocation, this._cbState);
} }

  源码位置:

http://pan.baidu.com/s/1jGJzErs

DataGridView中实现checkbox全选的自定义控件的更多相关文章

  1. 关于Winform下DataGridView中实现checkbox全选反选、同步列表项的处理

    近期接手一个winform 项目,虽然之前有.net 的经验,但是对一些控件的用法还不是很熟悉. 这段时间将会记录一些在工作中遇到的坎坷以及对应的解决办法,写出来与大家分享并希望大神提出更好解决方法来 ...

  2. vue中的checkbox全选和反选

    前几天有个博客园的朋友问小颖,小颖之前写的vue2.0在table中实现全选和反选  .Vue.js实现checkbox的全选和反选,为什么他将里面的js复制下来,但是实现不了全选和反选.小颖当时看他 ...

  3. datagridview里面的checkbox全选和取消全选

    全选 设置全选button,选中所有的checkbox private void selectAll_Click(object sender, EventArgs e) { //遍历datagridv ...

  4. C# WinForm中实现CheckBox全选反选功能

    今天一群里有人问到这个功能,其实应该挺简单,但提问题的人问题的出发点并没有描述清楚.因此,一个简简单单的需求,就引起了群内热烈的讨论.下面看看这个功能如何去实现,先上效果: 下面直接上代码,请不要在意 ...

  5. DataGrid列中加入CheckBox 全选 点击Header全选 和 只操作选中部分 功能的实现

    先写个效果 中午接着写 反正没人看 只是给自己记录

  6. 利用jQuery实现CheckBox全选/全不选/反选

    转自:http://www.cnblogs.com/linjiqin/p/3148259.html jQuery有些版本中实现CheckBox全选/全不选/反选会有bug,经测试jquery-1.3. ...

  7. jquery中checkbox全选失效的解决方法

    这篇文章主要介绍了jquery中checkbox全选失效的解决方法,需要的朋友可以参考下     如果你使用jQuery 1.6 ,代码if ( $(elem).attr(“checked”) ),将 ...

  8. Datagridview 添加checkbox列,并判断Datagridview 中的checkbox列是否被选中

    Solution1://In Fill DataGridViewEvent : DataGridViewCheckBoxColumn ChCol = new DataGridViewCheckBoxC ...

  9. JS checkbox 全选 全不选

    /* JS checkbox 全选 全不选 Html中checkbox: <input type="checkbox" name="cbx" value= ...

随机推荐

  1. USACO翻译:USACO 2014 MARCH Silver三题

    USACO 2014 MARCH 一.题目概览 中文题目名称 农田灌溉 懒牛 牛叫 英文题目名称 irrigation lazy mooomoo 可执行文件名 irrigation lazy mooo ...

  2. 农业银行快捷支付php版说明和实例代码

    接入的是shopnc,代码改改就可以用了,虽然不是一个完善的类,也可以按照类的方法直接调用,省得再去扣开发文档 农行在接收返回信息也会验证一次,还有一点就是页面通知返回结果 一定要用服务器通知,不然会 ...

  3. c++代码中,使用svn版本号作为程序版本号的实现方法

    1.编写版本模板文件 #ifndef _VERSIONSVN_H_#define _VERSIONSVN_H_#define VER_REVISIONSVN $WCREV$#endif //!_VER ...

  4. Vue.js起手式+Vue小作品实战

    本文是小羊根据Vue.js文档进行解读的第一篇文章,主要内容涵盖Vue.js的基础部分的知识的,文章顺序基本按照官方文档的顺序,每个知识点现附上代码,然后根据代码给予个人的一些理解,最后还放上在线编辑 ...

  5. QList

    #include <QCoreApplication> #include<QList> #include<QDebug> int main(int argc, ch ...

  6. mongodb权限管理

    说到mongodb就得先谈谈mongodb的用户组,和传统的关系型数据库不一样,mongodb并没有在创建应用时就要求创建权限管理组,所以类似于Robomongo这样的数据库可视化工具在创建conne ...

  7. 使用PowerShell解三道测试开发笔试题

    在网上看到了三道测试开发的笔试题,答案是用Python解的.这段时间正好在学PowerShell,练习一下:) 1. 验证邮箱格式 2. 获取URL的后缀名 3. 获取前一天时间或前一秒 我的解法是: ...

  8. An error occurred while processing an SVN command

    今天在使用SmartSVN的时候,遇到这个问题,反复几次,也没有得到解决,而且进入了死循环,一直在提示这个消息,即使在cleanup之后. 百度了一番之后,找到了解决办法: 把出错的文件在本地删除掉, ...

  9. Java 的静态代理 动态代理(JDK和cglib)

    转载:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是 ...

  10. 【转载】JMeter学习(三十六)发送HTTPS请求

    Jmeter一般来说是压力测试的利器,最近想尝试jmeter和BeanShell进行接口测试.由于在云阅读接口测试的过程中需要进行登录操作,而登录请求是HTTPS协议.这就需要对jmeter进行设置. ...