DataGridView控件列头添加CheckBox

DataGridView控件是CS架构中用的比较频繁的一个控件,里面提供了checkbox列的功能,可是却没有在列头给出checkbox控件用于全选/全部取消所有行的功能,确实是个遗憾,这里就通过绘制实现这个功能.

  1. 添加一个帮助类DataGridViewCheckBoxHeaderCell,用于绘制列头checkbox和创建鼠标单击事件,代码如下:
     public class DataGridViewCheckBoxHeaderCell : DataGridViewColumnHeaderCell
        {
            public delegate void DataGridViewCheckBoxHeaderEventHander(object sender, DataGridViewCheckBoxHeaderEventArgs e);
    
            private Point checkBoxLocation;
            private Size checkBoxSize;
            private bool _checked = false;
            private Point _cellLocation = new Point();
    
            private System.Windows.Forms.VisualStyles.CheckBoxState _cbState =
                System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal;
    
            public event DataGridViewCheckBoxHeaderEventHander OnCheckBoxClicked;
    
    
            //绘制列头checkbox
            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/2) - (s.Width/2) - 1; //列头checkbox的X坐标
                p.Y = cellBounds.Location.Y +
                      (cellBounds.Height/2) - (s.Height/2); //列头checkbox的Y坐标
                _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);
            }
          
            /// <summary>
            /// 点击列头checkbox单击事件
            /// </summary>
            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;
    
    
                    //获取列头checkbox的选择状态
                    DataGridViewCheckBoxHeaderEventArgs ex = new DataGridViewCheckBoxHeaderEventArgs();
                    ex.CheckedState = _checked;
    
                    object sender = new object(); //此处不代表选择的列头checkbox,只是作为参数传递。应该列头checkbox是绘制出来的,无法获得它的实例
    
                    if (OnCheckBoxClicked != null)
                    {
                        OnCheckBoxClicked(sender, ex); //触发单击事件
                        this.DataGridView.InvalidateCell(this);
                    }
                }
                base.OnMouseClick(e);
            }
        }
    
        //定义包含列头checkbox选择状态的参数类
        public class DataGridViewCheckBoxHeaderEventArgs : EventArgs
        {
            private bool checkedState;
    
            public bool CheckedState
            {
                get { return checkedState; }
                set { checkedState = value; }
            }
        }

     

  2. 在有DataGridView的界面,添加代码如下:
            /// <summary>
            ///给DataGridView添加checkbox列头
            /// </summary>
            private void AddCheckboxCell()
            {
                DataGridViewCheckBoxHeaderCell ch = new DataGridViewCheckBoxHeaderCell();
                ch.OnCheckBoxClicked += new DataGridViewCheckBoxHeaderCell.DataGridViewCheckBoxHeaderEventHander(ch_OnCheckBoxClicked);
                //第一列为DataGridViewCheckBoxColumn
                DataGridViewCheckBoxColumn checkboxCol = new DataGridViewCheckBoxColumn();
                checkboxCol.HeaderCell = ch;
                checkboxCol.HeaderCell.Value = string.Empty; //消除列头checkbox旁出现的文字
                this.dgvSelectAll.Columns.Insert(0, checkboxCol);
            }
            void ch_OnCheckBoxClicked(object sender, DataGridViewCheckBoxHeaderEventArgs e)
            {
                foreach (DataGridViewRow dgvRow in this.dgvSelectAll.Rows)
                {
                    dgvRow.Cells[0].Value = e.CheckedState;
                }
                this.dgvSelectAll.RefreshEdit();
            }

     

     
posted @ 2013-01-02 22:19  超级塞亚人  阅读(593)  评论(0)    收藏  举报