为了账号安全,请及时绑定邮箱和手机立即绑定

C#总结(三)DataGridView增加全选列

标签:
C#

最近的一个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下载
点击查看更多内容
8人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
全栈工程师
手记
粉丝
40
获赞与收藏
254

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消