DataGridView中实现checkbox全选的自定义控件

在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 = 0;
        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>=0&&e.ColumnIndex>=0)
            {
                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 > 0)
                    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

时间: 2024-12-15 06:54:40

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

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

近期接手一个winform 项目,虽然之前有.net 的经验,但是对一些控件的用法还不是很熟悉. 这段时间将会记录一些在工作中遇到的坎坷以及对应的解决办法,写出来与大家分享并希望大神提出更好解决方法来促进进步. 我也会尽可能把我查找到资料的出处引出来,以此来感恩对我提供帮助的人们. 正题如下 一.关于Winform下DataGridView中实现checkbox全选反选.同步列表项的处理 1.checkbox的添加:在设计页面选择编辑列在新添加的列中注意如下几个属性: SortMode = No

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

全选 设置全选button,选中所有的checkbox private void selectAll_Click(object sender, EventArgs e) { //遍历datagridview中的每一行,判断是否选中,若为选中,则选中 for (int i = 0; i < dataGridView1.Rows.Count; i++) { if ((Convert.ToBoolean(dataGridView1.Rows[i].Cells[0].Value) == false))

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

转自:http://www.cnblogs.com/linjiqin/p/3148259.html jQuery有些版本中实现CheckBox全选/全不选/反选会有bug,经测试jquery-1.3.1.js–>测试通过,jquery-1.5.1.js–>测试不通过. 实现CheckBox全选/全不选/反选代码如下: <%@ page language="java" pageEncoding="UTF-8"%>   <!DOCTYPE

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

这篇文章主要介绍了jquery中checkbox全选失效的解决方法,需要的朋友可以参考下 如果你使用jQuery 1.6 ,代码if ( $(elem).attr(“checked”) ),将获得一个属性(attribute) ,它不改变该复选框被选中和选中.它只是用来存储默认或选中属性的初始值.为了保持向后兼容,.attr() 方法从 jQuery 1.6.1+ 开始除了返回属性值外,还会更新 property 属性,因此 boolean attribute(布尔属性)不需要通过 .prop(

页面中公用的全选按钮,单选按钮组件的编写

相应的js代码为: var checkAll = $("[data-checkbox-checkall]"); //遍历处理每一组的情况 checkAll.each(function(){ var groupName = $(this).attr("data-checkbox-group"); startCheck(groupName); }); function startCheck(groupName){ //所有的该组元素 var allCheckbox =

JS中表格的全选和删除要注意的问题

在项目开发中,由于刚刚开始做项目,我对js还不是很精通,所以在用js对表格的全选和删除中遇到了不少问题,后来通过查找资料解决了,之后总结了一下关于js表格的全选和删除出现的一些问题,希望能帮助到大家. 以下是我自己做的一个小例子,用来更简单明了的说明js全选和删除. 一.全选的说明:当选中全选的checkbox时,下面1-5都会选中,没有选中时1-5都不会选中,这个实现不难,步骤如下: 1.获取全选框的选中状态, 2.for循环设置所有的单选框的选中状态 主要代码: //1.获取全选按钮 var

checkbox 全选,反选 ,全不选

在表格或者列表中经常会遇到要全选或者反选等交互,今天总结了一下代码,保留着以后直接拿来用 原理: 1. 全选:当全选checkbox被点击(不管点击之前是什么状态)后,获取其checked状态.然后对列表进行循环检测,此时可以将所有的(无论之前什么状态),设为选中,也可对未选中的进行选中. 2. 反选:当反选checkbox被点击(不管点击之前是什么装填)后,获取其其状态值,对列表进行循环检测,将被检测的元素的checked状态反向处理,即可. 3. 列表全选或者不全选:当列表中的任意一个che

datagridview中使用checkbox问题。

如果套用datagridview中的checkboxfield,生成的数据,会出现无法选择datagridview中数据项的问题,即checkbox不可以被鼠标点击,选中/取消选中.此checkbox的选中与否,完全取决于数据库,表中的bool值得类型,当值为true的时候,生成的datagridview中的checkbox是处于勾选状态的,要想取消勾选,需要通过sql语句,来修改后台数据库表中的对应字段的值(把true改成false).这种方法比较烦. 另一种比较好的做法是在datagridv

练习-checkbox 全选 ,反选, 单选,以及取值

1.方法1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>全选与反选</title> <meta http-equiv="Content-Type" content="te