自己写个代码生成器,没想到还要来实现DataGridView列头CheckBox全选功能。在网上找了一些例子,复制下来感觉视觉不够美观,操作不够人性化(懒)。所以写了个例子。
思路如下,点击更改HeaderCheckBox时,分两种情况:1 没有选择任何一行时,更改所有行;2 有选中行时,只更改选中的行记录,3 列头背景要跟DataGridView设置的一样,不要加个CheckBox外观就怪怪的。
代码如下:private DataGridView DGV = new DataGridView();//DataGridView private CheckBox HeaderCheckBox使用 = null; private CheckBox HeaderCheckBox允许空 =null; public FrMain() { InitializeComponent(); if(!DesignMode )//设计时是别想看效果了,效果靠运行时看。 { //设置列头外观,并固定列宽 HeaderCheckBox使用 = new CheckBox() { Text = DGV.Columns[0].HeaderText ,BackColor=Color.Transparent }; //背景色透明 HeaderCheckBox允许空 = new CheckBox() { Text = DGV.Columns[9].HeaderText, BackColor = Color.Transparent }; DGV.Columns[0].HeaderText = DGV.Columns[9].HeaderText = ""; DGV.Columns[0].Resizable = DGV.Columns[9].Resizable = DataGridViewTriState.False; HeaderCheckBox使用.MouseClick += HeaderCheckBox使用_MouseClick; HeaderCheckBox允许空.MouseClick += HeaderCheckBox允许空_MouseClick; //CheckBox加入DataGridView容器 DGV.Controls.AddRange(new Control[] { HeaderCheckBox使用, HeaderCheckBox允许空 }); //单元格重画 DGV.CellPainting += DGV_CellPainting; } } /// 列头处理,单元格重画。 /// private void DGV_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) { if (e.RowIndex == -1 && e.ColumnIndex == 0) ResetHeaderCheckBoxLocation(e.ColumnIndex, e.RowIndex, HeaderCheckBox使用); if (e.RowIndex == -1 && e.ColumnIndex == 9) ResetHeaderCheckBoxLocation(e.ColumnIndex, e.RowIndex, HeaderCheckBox允许空); } private void ResetHeaderCheckBoxLocation(int ColumnIndex, int RowIndex,CheckBox HeaderCheckBox) { /*因为居中的话列标题文字左边有方框,导致列标题经常显示不完整,要不就占用很大列宽*/ Rectangle oRectangle = this.DGV.GetCellDisplayRectangle(ColumnIndex, RowIndex, true); Point oPoint = new Point(); oPoint.X = oRectangle.Location.X + (oRectangle.Width - HeaderCheckBox.Width)+1; oPoint.Y = oRectangle.Location.Y + (oRectangle.Height - HeaderCheckBox.Height)+1 ; HeaderCheckBox.Location = oPoint; HeaderCheckBox.Size = new Size(oRectangle.Width-2, oRectangle.Height-2); } private void HeaderCheckBox允许空_MouseClick(object sender, MouseEventArgs e) {HeaderCheckBox_Checked(sender, e); } private void HeaderCheckBox使用_MouseClick(object sender, MouseEventArgs e) { HeaderCheckBox_Checked(sender, e); } private void HeaderCheckBox_Checked(object sender, EventArgs e) { DGV.EndEdit(); //结束最后选中的行退出编辑状态,使之能刷新。不然该行CheckBox状态不改变。 CheckBox sr = (CheckBox)sender; int colIndex = sr == HeaderCheckBox允许空 ? 9 : 0 ; if (DGV.SelectedRows.Count == 0) //如果没选更改所有行,否则只更改选中行。 foreach (DataGridViewRow dgvr in DGV.Rows) ((DataGridViewCheckBoxCell)dgvr.Cells[colIndex]).Value = sr.Checked; else foreach (DataGridViewRow dgvr in DGV.SelectedRows) ((DataGridViewCheckBoxCell)dgvr.Cells[colIndex]).Value = sr.Checked; }