如何在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 / 2) - (s.Width / 2) - 1;

            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;



                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属性变化了。

  效果图:

如何在datagridview 的head上绘制一个全选按钮

你可能感兴趣的:(datagridview)