zoukankan      html  css  js  c++  java
  • DataGridView增加全选列

    最近的一个winform的项目中,碰到datagridview控件的第一列添加全选的功能,通常这个功能,有两种实现方式:1. 为控件添加DataGridViewCheckBoxColumn来实现,但是需要提供全选反选功能,2. 再加一个checkbox控件跟datagridview组合来实现全选反选功能。但是,感觉这两种实现效果都不是很好。网上查资料,发现一个老外的实现方法,比较简单通用。demo 代码最下面的连接给出。

      他的实现方式就是:DataGridViewCheckBoxColumn的父类DataGridViewColumnHeaderCell 里面有个HeaderCell的属性,看下DataGridViewColumnHeaderCell 的继承关系,就可以知道它继承自DataGridViewCell类, 所以只需要重写DataGridViewColumnHeaderCell类的paint方法,用CheckBoxRenderer画一个Checkbox到单元格上。即可实现在datagridview的列头增加一个全选的checkbox 。以下是实现代码:

      

      实现代码

    复制代码
    public delegate void CheckBoxClickedHandler(bool state);
        public class DataGridViewCheckBoxHeaderCellEventArgs : EventArgs
        {
            bool _bChecked;
            public DataGridViewCheckBoxHeaderCellEventArgs(bool bChecked)
            {
                _bChecked = bChecked;
            }
            public bool Checked
            {
                get { return _bChecked; }
            }
        }
        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 CheckBoxClickedHandler OnCheckBoxClicked;
     
            public DatagridViewCheckBoxHeaderCell()
            {           
            }
    
            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) ;
                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;
                    if (OnCheckBoxClicked != null)
                    {
                        OnCheckBoxClicked(_checked);
                        this.DataGridView.InvalidateCell(this);
                    }
                    
                } 
                base.OnMouseClick(e);
            }     
        }
    复制代码

      

      调用方式

    DataGridViewCheckBoxColumn colCB = new DataGridViewCheckBoxColumn();
    DatagridViewCheckBoxHeaderCell cbHeader = new DatagridViewCheckBoxHeaderCell();
    colCB.HeaderCell = cbHeader;
    datagridview1.Columns.Add(colCB);
    cbHeader.OnCheckBoxClicked += 
        new CheckBoxClickedHandler(cbHeader_OnCheckBoxClicked);

      1. 我们只需要定义一个DataGridViewCheckBoxColumn。

      2. 然后为每一行的checkbox 定义一个CheckboxClicked 事件。

      测试程序

      创建一个Winform 项目,加个datagridview控件,初始化几行默认数据。注意:datagirdview有编辑状态,如果有一行数据在编辑状态,那这一行被编辑。

      解决办法就是在事件的绑定方法里面增加EndEdit()调用。

    复制代码
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
    
                InitDtSource();
            }
    
            private void cbHeader_OnCheckBoxClicked(bool state)
            {
                //这一句很重要结束编辑状态
                dgInfo.EndEdit();
                dgInfo.Rows.OfType<DataGridViewRow>().ToList().ForEach(t => t.Cells[0].Value = state);
            }
    
            private void InitDtSource()
            {
                try
                {
                    var _dtSource = new DataTable();
                    //1、添加列
                    _dtSource.Columns.Add("姓名", typeof(string)); //数据类型为 文本
                    _dtSource.Columns.Add("身份证号", typeof(string)); //数据类型为 文本
                    _dtSource.Columns.Add("时间", typeof(string)); //数据类型为 文本
                    _dtSource.Columns.Add("地点", typeof(string)); //数据类型为 文本
    
                    for (int i = 0; i < 10; i++)
                    {
                        DataRow drData = _dtSource.NewRow();
                        drData[0] = "test" + i;
                        drData[1] = "35412549554521263" + i;
                        drData[2] = "2017-05-21 10:55:21";
                        drData[3] = "北京市";
                        _dtSource.Rows.Add(drData);
                    }
    
                    dgInfo.DataSource = _dtSource;
    
                    InitColumnInfo();
                }
                catch (Exception ex)
                {
    
                }
            }
    
            private void InitColumnInfo()
            {
                int index = 0;
    
                DataGridViewCheckBoxColumn colCB = new DataGridViewCheckBoxColumn();
                DatagridViewCheckBoxHeaderCell cbHeader = new DatagridViewCheckBoxHeaderCell();
                colCB.HeaderCell = cbHeader;
                colCB.HeaderText = "全选";
                cbHeader.OnCheckBoxClicked += new CheckBoxClickedHandler(cbHeader_OnCheckBoxClicked);
                dgInfo.Columns.Insert(index, colCB);
    
    
                index++;
                dgInfo.Columns[index].HeaderText = "姓名";
                dgInfo.Columns[index].Width = 90;
    
                index++;
                dgInfo.Columns[index].HeaderText = "身份证号";
                dgInfo.Columns[index].Width = 120;
    
                index++;
                dgInfo.Columns[index].HeaderText = "时间";
                dgInfo.Columns[index].Width = 150;
    
                index++;
                dgInfo.Columns[index].HeaderText = "地点";
                dgInfo.Columns[index].Width = 100;
    
                System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
                dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;//211, 223, 240
                dataGridViewCellStyle2.ForeColor = System.Drawing.Color.Blue;
                dataGridViewCellStyle2.SelectionForeColor = System.Drawing.Color.Blue;
                dgInfo.Columns[index].DefaultCellStyle = dataGridViewCellStyle2;
            }
        }
    复制代码

      其他

      1. 参考地址:https://www.codeproject.com/Articles/20165/CheckBox-Header-Column-For-DataGridView

      2. Demo下载

    转自-https://www.cnblogs.com/zhangweizhong/p/6885507.html

  • 相关阅读:
    剑指offer:复杂链表的复制
    剑值offer:最小的k个数
    剑指offer:第一个只出现一次的字符
    剑指offer:树的子结构
    leetcode 240搜索二维矩阵
    leetcode 22括号生成
    leetcode 79 单词搜索
    leetcode 17电话号码的字母组合
    leetcode 78子集
    leetcode 105从前序与中序遍历序列构造二叉树
  • 原文地址:https://www.cnblogs.com/asdyzh/p/9944297.html
Copyright © 2011-2022 走看看