如何在datagridview 的head上绘制一个全选按钮
winform的项目中,经常要用到datagridview控件,但是为控件添加DataGridViewCheckBoxColumn来实现数据行选择这个功能的时候,经常需要提供全选反选功能,如果不重绘控件的话,我们只能再加一个checkbox控件跟datagridview组合来实现全选反选功能,实现了功能,却不是我们想要的效果。
当我们添加一个DataGridViewCheckBoxColumn时,发现他的基类里面有个HeaderCell的属性,而且是可写的,也就是DataGridViewColumnHeaderCell这个类,然后再看下继承关系,它最终也是继承自DataGridViewCell类,也就是一个单元格。知道这个以后,问题就很容易解决了,只需要重写下DataGridViewColumnHeaderCell类的paint方法,用CheckBoxRenderer画一个Checkbox到单元格上不就解决了。以下是实现代码:
    public delegate void DataGridViewCheckBoxHeaderEventHander(object sender, datagridviewCheckboxHeaderEventArgs e);
    public class datagridviewCheckboxHeaderEventArgs : EventArgs
    {
        private bool checkedState = false;
        public bool CheckedState
        {
            get { return checkedState; }
            set { checkedState = value; }
        }
    }
    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 DataGridViewCheckBoxHeaderEventHander OnCheckBoxClicked;
        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 p = new Point();
            Size s = CheckBoxRenderer.GetGlyphSize(graphics,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;
                datagridviewCheckboxHeaderEventArgs ex = new datagridviewCheckboxHeaderEventArgs();
                ex.CheckedState = _checked;
                object sender = new object();
                if (OnCheckBoxClicked != null)
                {
                    OnCheckBoxClicked(sender, ex);
                    this.DataGridView.InvalidateCell(this);
                }
            }
            base.OnMouseClick(e);
        }
    }
使用的时候,只需要将自己定义的DataGridViewCheckBoxHeaderCell赋给HeadCell属性,然后将HeaderCell.Value的值置为空,最后注册OnMouseClick事件,就可以在参数中接收checkbox的checked属性变化了。
效果图:

TF@PY{P3I.jpg)
如何在datagridview 的head上绘制一个全选按钮的更多相关文章
- C#Winform窗体 DataGridView全选按钮的实现方式
		
最近,在做CS程序遇到一个头疼的问题,datagridview列表的全选按钮遇到各种问题,做的是自适应窗体大小,当窗体最大化导致全选按钮出现与列表数据不一致,特别不搭配,试了很久,网上也找了好多资料各 ...
 - 用Vue实现一个全选指令
		
最近用vue做了两个项目,都需要实现全选反选的功能,两个项目用了两种实现方法,第一个项目用vue的computed,第二个项目用指令来实现,用起来,发觉指令更加方便. 第一次做全选的时候是刚开始接触v ...
 - js做全选,用一个checkbox复选框做多个checkbox复选框的全选按钮,有一个复选框未被选择时,全选按钮的checked就为false
		
用一个checkbox复选框做多个checkbox复选框的全选按钮,有一个复选框未被选择时,全选按钮的checked就为false,当所有checkbox都被选中时,全选按钮也被选中. 详解: 有两种 ...
 - angular4.x实现一个全选,反选,外加从下一页返回上一页,选中上一次的操作记录
		
productMap:any = new Map<string, string>(); //定义一个map的数据模型 //只要操作这个checkbox 那么只管把数据全部勾起了就行了 刷新 ...
 - jQuery实现一个全选复选框联动效果
		
类似邮件列表里的复选框 要求双向联动 ☛ [实现]: <body> <div> <input type="checkbox" name="c ...
 - 如何在repeater中找到checkbox并实现全选删除
		
checkbox使用客户端控件,且给repeater里边的checkbox添加ruanat=server属性表头中的chkTotal的属性一定不要加此属性....然后 全选的javascript代码 ...
 - 如何在WPF的DiagramControl中绘制一个类型数据关系图的方法
		
https://www.devexpress.com/Support/Center/Question/Details/T418156 虽然是在wpf中,但是在win中也可以调用wpf控件,这个太棒了, ...
 - vue中两行代码实现全选及子选项全部选中,则全选按钮选中,反之有一个没选中,就取消选中全选按钮
		
every() 方法使用指定函数检测数组中的所有元素: 如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测. 如果所有元素都满足条件,则返回 true. 逻辑 ...
 - 1如何给devexpress的gridview控件绘制全选按钮
		
1 首先注册gridview的this.edibandedGridView.CustomDrawColumnHeader += EdibandedGridView_CustomDrawColumnHe ...
 
随机推荐
- shell script针对参数已经有配置好变量名称
			
/path/to/scriptname opt1 opt2 opt3 opt4 $ $ $ $ $ 这样够清楚了吧?运行的脚本档名为 $0 这个变量,第一个接的参数就是 $1 啊- 所以,只要我们在 ...
 - MIRO发票校验BAPI_INCOMINGINVOICE_CREATE (2013-01-23 10:01:29)
			
form frm_invoice_create2 . data: str type string. data: ls_headerdata like bapi_incinv_creat ...
 - Mysql 命令行工具
			
1.Mysql命令行工具分为两类:服务端命令行工具和客户端命令行工具. 2.服务端工具 mysql_install_db:建库工具 mysqld_safe:Mysql服务的启动工具,mysqld_sa ...
 - 十种JAVA排序算法实例
			
一.冒泡(Bubble)排序 复制代码 代码如下: void BubbleSortArray() { for(int i=1;i<n;i++) { for ...
 - python中super关键字的用法
			
http://python.jobbole.com/86787/ class A: def __init__(self): print "enter A" print ...
 - view的封装
			
如果一个view内部的子控件比较多,一般会考虑自定义一个view,把它内部子控件的创建屏蔽起来,不让外界关心 外界可以传入对应的模型数据给view,view拿到模型数据后给内部的子控件设置对应的数据 ...
 - Object Pascal 控制语句
			
控制语句 1.常量声明语句常量在声明时就被赋予了一个值,在程序执行过程中是不可改变的. 格式 const 常量名 :数据类型 = 值 下面的例子声明了3 个常量: const Pi = 3.14159 ...
 - Android网络编程系列 一 TCP/IP协议族之传输层
			
这篇借鉴的文章主要是用于后续文章知识点的扩散,在此特作备份和扩散学习交流. 传输层中有TCP协议与UDP协议. 1.UDP介绍 UDP是传输层协议,和TCP协议处于一个分层中,但是与TCP协议不同,U ...
 - Javascript 弱类型:除法结果是小数
			
由于javascript是弱类型,只有一种var类型,所以在运算时不会自动强制转换,所以计算的结果是多少就是多少,但java中的17/10的结果就是1(强类型与弱类型)比如:console.log(M ...
 - 测试分页查询出数据并分文件导出[java工程]
			
package cn.shiyanjun.test; import java.util.ArrayList; import java.util.List; public class ExcelTest ...