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屬性變化了。
效果圖:

