Winform中DatagridView 表头实现一个加上一个checkBox,实现全选选项功能

实现效果

点击checkBox1或者直接在第一列列表头点击即可实现

代码实现

我的datagridview叫dgv

我在datagridview已经默认添加了一个DataGridViewCheckBoxColumn ,勾选时value为1,不勾选时value为0

第一种通过可视化拖动一个checkBox来实现

拖动组件,然后绑定事件

点击事件

事件代码:

java 复制代码
		/// <summary>
        /// checkbox1的点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkSelectAll_CheckedChanged(object sender, EventArgs e)
        {
            if (checkSelectAll.Checked)
            {
                foreach (DataGridViewRow dgvRow in this.dgv.Rows)
                {
                    dgvRow.Cells["dataGridViewCheckBoxColumn1"].Value = true;
                }
            }
            else
            {
                foreach (DataGridViewRow dgvRow in this.dgv.Rows)
                {
                    dgvRow.Cells["dataGridViewCheckBoxColumn1"].Value = false;
                }
            }

        }

第二种,自定义checkBox,添加到列头

这种需要自己弄一个DataGridViewCheckBoxColumn
文件位置

详细代码

==DatagridviewCheckboxHeaderCell ==

java 复制代码
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WindowsFormsApp20230728.Properties;

namespace WindowsFormsApp20230728
{
    //定义触发单击事件的委托
    public delegate void DatagridviewcheckboxHeaderEventHander(object sender, DatagridviewCheckboxHeaderEventArgs e);

    //定义继承于DataGridViewColumnHeaderCell的类,用于绘制checkbox,定义checkbox鼠标单击事件
    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;
        
        
 
        //绘制列头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)
        {
            var 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 { CheckedState = _checked };
                
                var sender = new object();//此处不代表选择的列头checkbox,只是作为参数传递。应该列头checkbox是绘制出来的,无法获得它的实例
                if (OnCheckBoxClicked != null)
                {
                    OnCheckBoxClicked(sender, ex);//触发单击事件
                    this.DataGridView.InvalidateCell(this);
                }
            }
            base.OnMouseClick(e);
        }
    }
}

==DatagridviewCheckboxHeaderEventArgs ==

java 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace WindowsFormsApp20230728
{
    //定义包含列头checkbox选择状态的参数类
    public class DatagridviewCheckboxHeaderEventArgs : EventArgs
    {
        public DatagridviewCheckboxHeaderEventArgs()
        {
            CheckedState = false;
        }
        public bool CheckedState
        {
            get { return _CheckedState; }

            set { _CheckedState = value; }
        }
        
        private bool _CheckedState;
    }
}

实现位置,均在Form2类中

代码:

java 复制代码
		public Form2()
        {
            InitializeComponent();
            //InitColumnInfo();
            #region  自定义组件开始
            //自定义组件实现
            var ch = new DatagridviewCheckboxHeaderCell();
            ch.OnCheckBoxClicked += new DatagridviewcheckboxHeaderEventHander(ch_OnCheckBoxClicked);
            var checkboxCol = this.dgv.Columns[0] as DataGridViewCheckBoxColumn;
            checkboxCol.HeaderCell = ch;
            checkboxCol.HeaderCell.Value = string.Empty;
         }

注意其中dgv.EndEdit(); 失去焦点操作,如果没有这个,你焦点所在checkBox不会勾选

java 复制代码
		//去除datagridview列表头排序
        //    foreach (DataGridViewColumn item in dgv.Columns)
        //        item.SortMode = DataGridViewColumnSortMode.NotSortable;
        /// <summary>
        /// 单击事件
        /// </summary>
        private void ch_OnCheckBoxClicked(object sender, DatagridviewCheckboxHeaderEventArgs e)
        {
            //失去焦点操作
            dgv.EndEdit();
            
            //Console.WriteLine(e.CheckedState.ToString());
            
            //选中事件操作
            if (e.CheckedState)
            {
                for(int i = 0; i < dgv.Rows.Count; i++)
                {
                    dgv.Rows[i].Cells[0].Value = 1;
                }
                //foreach (DataGridViewRow dgvRow in this.dgv.Rows)
                //{
                //    dgvRow.Cells["dataGridViewCheckBoxColumn1"].Value = true;
                //}
            }
            else
            {
                for (int i = 0; i < dgv.Rows.Count; i++)
                {
                    dgv.Rows[i].Cells[0].Value = 0;
                }
                //foreach (DataGridViewRow dgvRow in this.dgv.Rows)
                //{
                //    dgvRow.Cells["dataGridViewCheckBoxColumn1"].Value = 0;
                //}
            }
            
        }

第三种,不添加DataGridViewCheckBoxColumn,直接以自定义的形式形成一列的checkBox

和第二种相比,就是把DataGridViewCheckBoxColumn从DataGridView中删除,然后public Form2()自定义组件实现代码改一下,其他都是一样的

也就是把这一串换成下面的即可

//自定义组件实现

var ch = new DatagridviewCheckboxHeaderCell();

ch.OnCheckBoxClicked += new DatagridviewcheckboxHeaderEventHander(ch_OnCheckBoxClicked);

var checkboxCol = this.dgv.Columns[0] as DataGridViewCheckBoxColumn;

checkboxCol.HeaderCell = ch;

checkboxCol.HeaderCell.Value = string.Empty;

java 复制代码
if (!this.DesignMode){
       DatagridviewCheckboxHeaderCell cbHeader = new DatagridviewCheckboxHeaderCell();
       cbHeader.OnCheckBoxClicked += new DatagridviewcheckboxHeaderEventHander(ch_OnCheckBoxClicked);
       DataGridViewCheckBoxColumn checkboxCol = new DataGridViewCheckBoxColumn();
       checkboxCol.HeaderCell = cbHeader;
       checkboxCol.HeaderCell.Value = string.Empty;
       this.dgv.Columns.Insert(0,checkboxCol);
}

第三种实现的是类属于java面向对象编程的效果,第二种则是自定义组件进行添加的效果

参考文章

C# Winform中DataGridView的DataGridViewCheckBoxColumn CheckBox选中判断
关于Winform中DatagridView 表头checkBox全选选项框总结
DataGridView EndEdit()方法
c# winform获取gridview数据

精髓概括

C# 自定义控件实现ChackBox的Checked效果

  1. 创建一个类,继承自System.Windows.Forms.Control,实现自定义控件;

  2. 在类中重写OnPaint方法,绘制CheckBox的外观;

  3. 在类中重写OnMouseDown方法,实现鼠标点击时CheckBox的Checked状态的改变;

  4. 在类中定义一个Checked属性,用于获取或设置CheckBox的Checked状态;

  5. 在类中定义一个CheckedChanged事件,用于在CheckBox的Checked状态改变时触发;

  6. 在类中重写OnClick方法,实现CheckBox的Checked状态改变时触发CheckedChanged事件。

配套功能实现

Winform中DatagridView 加上 ContextMenuStrip 实现右键点击展示菜单,且可以获取数据(在没数据的地方不显示右键菜单,以及右键焦点进行改变),详情见该栏上一篇文章

相关推荐
Envyᥫᩣ4 小时前
C#语言:从入门到精通
开发语言·c#
布说在见10 小时前
魅力标签云,奇幻词云图 —— 数据可视化新境界
信息可视化·数据挖掘·数据分析
IT技术分享社区10 小时前
C#实战:使用腾讯云识别服务轻松提取火车票信息
开发语言·c#·云计算·腾讯云·共识算法
千汇数据的老司机11 小时前
webGIS在可视化大屏中的应用场景有哪些,有哪些类库
信息可视化·webgis·#web
小华同学ai12 小时前
AJ-Report:一款开源且非常强大的数据可视化大屏和报表工具
数据库·信息可视化·开源
△曉風殘月〆17 小时前
WPF MVVM入门系列教程(二、依赖属性)
c#·wpf·mvvm
逐·風18 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
m0_656974741 天前
C#中的集合类及其使用
开发语言·c#
九鼎科技-Leo1 天前
了解 .NET 运行时与 .NET 框架:基础概念与相互关系
windows·c#·.net
布说在见1 天前
层次与网络的视觉对话:树图与力引导布局的双剑合璧
信息可视化·数据挖掘·数据分析