通过绘制在datagridview控件列头添加一个checkbox控件

来源:互联网 发布:sqlserver存储过程list 编辑:程序博客网 时间:2024/06/08 01:23

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

      该程序参考codeproject上的程序,网址如下:

      http://www.codeproject.com/KB/grid/CheckBoxHeaderCell.aspx  向其致敬!

 

一.创建一个表,里面包含bit字段,datagridview的DataGridViewCheckBoxColumn列会自动将其转换成checkbox列

见表语句如下,数据库名为testDB

CREATE TABLE [dbo].[UserInfo] (
 [RID] [varchar] (32) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [username] [varchar] (10) COLLATE Chinese_PRC_CI_AS NULL ,
 [gendar] [bit] NULL
) ON [PRIMARY]

 

二.主要代码

datagridviewCheckboxHeaderEventArgs类,用在在checkbox单击事件中提供类头checkbox的选择状态

 


 1    //定义包含列头checkbox选择状态的参数类
 2     class datagridviewCheckboxHeaderEventArgs : EventArgs
 3     {
 4         private bool checkedState = false;
 5 
 6         public bool CheckedState
 7         {
 8             get { return checkedState; }
 9             set { checkedState = value; }
10         }
11     }

 

datagridviewCheckboxHeaderCell类,这是个关键列,用于绘制列头checkbox和创建鼠标单击事件

 


 1   //定义继承于DataGridViewColumnHeaderCell的类,用于绘制checkbox,定义checkbox鼠标单击事件
 2     class datagridviewCheckboxHeaderCell : DataGridViewColumnHeaderCell
 3     {
 4         Point checkBoxLocation;
 5         Size checkBoxSize;
 6         bool _checked = false;
 7         Point _cellLocation = new Point();
 8         System.Windows.Forms.VisualStyles.CheckBoxState _cbState =
 9             System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal;
10         public event datagridviewcheckboxHeaderEventHander OnCheckBoxClicked;
11 
12 
13         //绘制列头checkbox
14         protected override void Paint(System.Drawing.Graphics graphics,
15            System.Drawing.Rectangle clipBounds,
16            System.Drawing.Rectangle cellBounds,
17            int rowIndex,
18            DataGridViewElementStates dataGridViewElementState,
19            object value,
20            object formattedValue,
21            string errorText,
22            DataGridViewCellStyle cellStyle,
23            DataGridViewAdvancedBorderStyle advancedBorderStyle,
24            DataGridViewPaintParts paintParts)
25         {
26             base.Paint(graphics, clipBounds, cellBounds, rowIndex,
27                 dataGridViewElementState, value,
28                 formattedValue, errorText, cellStyle,
29                 advancedBorderStyle, paintParts);
30             Point p = new Point();
31             Size s = CheckBoxRenderer.GetGlyphSize(graphics,
32             System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);
33             p.X = cellBounds.Location.X +
34                 (cellBounds.Width / 2- (s.Width / 2- 1;//列头checkbox的X坐标
35             p.Y = cellBounds.Location.Y +
36                 (cellBounds.Height / 2- (s.Height / 2);//列头checkbox的Y坐标
37             _cellLocation = cellBounds.Location;
38             checkBoxLocation = p;
39             checkBoxSize = s;
40             if (_checked)
41                 _cbState = System.Windows.Forms.VisualStyles.
42                     CheckBoxState.CheckedNormal;
43             else
44                 _cbState = System.Windows.Forms.VisualStyles.
45                     CheckBoxState.UncheckedNormal;
46             CheckBoxRenderer.DrawCheckBox
47             (graphics, checkBoxLocation, _cbState);
48         }
49 
50 
51 
52         /// <summary>
53         /// 点击列头checkbox单击事件
54         /// </summary>
55         protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
56         {
57 
58             Point p = new Point(e.X + _cellLocation.X, e.Y + _cellLocation.Y);
59             if (p.X >= checkBoxLocation.X && p.X <=
60                 checkBoxLocation.X + checkBoxSize.Width
61             && p.Y >= checkBoxLocation.Y && p.Y <=
62                 checkBoxLocation.Y + checkBoxSize.Height)
63             {
64                 _checked = !_checked;
65 
66 
67                 //获取列头checkbox的选择状态
68                 datagridviewCheckboxHeaderEventArgs ex = new datagridviewCheckboxHeaderEventArgs();
69                 ex.CheckedState = _checked;
70 
71                 object sender = new object();//此处不代表选择的列头checkbox,只是作为参数传递。应该列头checkbox是绘制出来的,无法获得它的实例
72 
73                 if (OnCheckBoxClicked != null)
74                 {
75                     OnCheckBoxClicked(sender, ex);//触发单击事件
76                     this.DataGridView.InvalidateCell(this);
77                 }
78 
79             }
80             base.OnMouseClick(e);
81         }
82 
83     }

 

 

还要定义和事件相关的委托:

    //定义触发单击事件的委托
    public delegate void datagridviewcheckboxHeaderEventHander(object sender, datagridviewCheckboxHeaderEventArgs e);

 

 

另外是界面操作代码:

 


 1   /// <summary>
 2         /// 加载数据
 3         /// </summary>
 4         private void btnLoadData_Click(object sender, EventArgs e)
 5         {
 6             DataTable dtTemp = new DataTable();
 7 
 8             using (SqlConnection con = new SqlConnection("server=.;uid=sa;pwd=sa;database=testdb;"))
 9             {
10                 SqlDataAdapter sa = new SqlDataAdapter("select * from userinfo", con);
11                 sa.Fill(dtTemp);
12             }
13 
14             this.dataGridView1.DataSource = dtTemp;
15         }
16 
17 
18         /// <summary>
19         /// 在checkbox列显示列头checkbox
20         /// </summary>
21         /// <param name="sender"></param>
22         /// <param name="e"></param>
23         private void button1_Click(object sender, EventArgs e)
24         {
25 
26             datagridviewCheckboxHeaderCell ch = new datagridviewCheckboxHeaderCell();
27             ch.OnCheckBoxClicked += new datagridviewcheckboxHeaderEventHander(ch_OnCheckBoxClicked);//关联单击事件
28 
29 
30             //第三列为DataGridViewCheckBoxColumn
31             DataGridViewCheckBoxColumn checkboxCol = this.dataGridView1.Columns[2as DataGridViewCheckBoxColumn;
32             checkboxCol.HeaderCell = ch;
33             checkboxCol.HeaderCell.Value = string.Empty;//消除列头checkbox旁出现的文字
34         }
35 
36         /// <summary>
37         /// 单击事件
38         /// </summary>
39         private void ch_OnCheckBoxClicked(object sender, datagridviewCheckboxHeaderEventArgs e)
40         {
41             foreach (DataGridViewRow dgvRow in this.dataGridView1.Rows)
42             {
43                 if (e.CheckedState)
44                 {
45                     dgvRow.Cells[2].Value = true;
46                 }
47                 else
48                 {
49                     dgvRow.Cells[2].Value = false;
50                 }
51             }
52         }