zoukankan      html  css  js  c++  java
  • 带CheckBox列头的DataGridView(二)

         上次从CodeProject上发现了一个老外写的开源的带CheckBox列头的类,当时就将文章翻译了过来并做成了一个小Demo,供大家参考,最近在开发中需要用到这个类,因此加以了改进,上次还有一个兄弟提到问怎样实现取消列表中选择的一行,列头的全选CheckBox也能处于不选中状态。这是一个很好的问题,我最近几天花了些时间,将其进行了些修改。终于可以实现这一功能了。废话不多说了,代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Drawing;
    using System.Windows.Forms;

    namespace chbDGV
    {
        public delegate void CheckBoxClickedHandler(bool state);

        /// <summary>
        /// 改变列头的CheckBox的状态
        /// </summary>
        /// <param name="state"></param>
        public delegate void ChangeCheckBoxStatusHandler(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 event ChangeCheckBoxStatusHandler OnChangeCheckBoxStatusHandler;

            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);
            }

            /// <summary>
            /// 改变列头CheckBox的状态的事件
            /// </summary>
            /// <param name="NewStatus"></param>
            public void OnChangeCheckBoxStatus(bool NewStatus)
            {
                if (OnCheckBoxClicked != null)
                {
                    _checked = NewStatus;
                    if (OnChangeCheckBoxStatusHandler != null)
                    {
                        OnChangeCheckBoxStatusHandler(NewStatus);
                    }
                    if (this.DataGridView != null)
                    {
                        this.DataGridView.InvalidateCell(this);
                    }
                }
            }

        }
    }

    测试的代码如下:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    namespace chbDGV
    {
        public partial class frmTestDGV : Form
        {

            DataGridViewCheckBoxColumn colCB = new DataGridViewCheckBoxColumn();
            DatagridViewCheckBoxHeaderCell cbHeader = new DatagridViewCheckBoxHeaderCell();
            DataTable dt = new DataTable();

            public frmTestDGV()
            {
                InitializeComponent();
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                BindDGV();
            }

            public override void Refresh()
            {

                base.Refresh();
            }

            private void cbHeader_OnCheckBoxClicked(bool Status)
            {
                for (int i = 0; i < dgvTest.Rows.Count; i++)
                {
                    dt.Rows[i]["Select"] = Status;
                }
            }

            private void BindDGV()
            {
                dt.Columns.Add("Select");
                dt.Columns.Add("ID");
                dt.Columns.Add("Code");
                dt.Columns.Add("Name");
                dt.Columns.Add("Desc");
                for (int i = 0; i < 5; i++)
                {
                    dt.Rows.Add();
                    dt.Rows[i][0] = false;
                    dt.Rows[i][1] = "100"+i.ToString();
                    dt.Rows[i][2] = "Lucy1001"+i.ToString();
                    dt.Rows[i][3] = "KateTest"+i.ToString();
                    dt.Rows[i][4] = "remark...";
                }

                colCB.HeaderCell = cbHeader;
               
                dgvTest.Columns.Insert(0, colCB);

                cbHeader.OnCheckBoxClicked +=
                new CheckBoxClickedHandler(cbHeader_OnCheckBoxClicked);

                dgvTest.AllowUserToAddRows = false;
                dgvTest.AutoGenerateColumns = false;
                dgvTest.DataSource = dt;


                this.colCB.DataPropertyName = "Select";
                this.ID.DataPropertyName = "ID";
                this.Code.DataPropertyName = "Code";
                this.TestName.DataPropertyName = "Name";
                this.Desc.DataPropertyName = "Desc";
               
            }

            /// <summary>
            /// 点击DataGridView的行
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void dgv_CellClick(object sender, DataGridViewCellEventArgs e)
            {
                DataGridView dgvv = ((DataGridView)sender);
                if (dgvTest.CurrentCell.OwningColumn.DataPropertyName == "Select")
                {
                    if (e.RowIndex != -1)
                    {
                        this.SetSelected(dgvv, e.RowIndex);
                    }
                }
            }

            /// <summary>
            /// 设置DataGridView的选择
            /// </summary>
            /// <param name="dgvb"></param>
            /// <param name="rowIndex"></param>
            private void SetSelected(DataGridView dgvb, int rowIndex)
            {
                if (dgvb.Rows[rowIndex] != null)
                {
                    if (dgvb.Rows[rowIndex].Cells[0].Value != null && dgvb.Rows[rowIndex].Cells[0].Value.ToString() != "")
                    {
                        bool status = !Convert.ToBoolean(dgvb.Rows[rowIndex].Cells[0].Value);
                        dt.Rows[rowIndex][0] = status;
                        dgvb.Rows[rowIndex].Cells[0].Value = status;
                        for (int i = 0; i < dgvb.Rows.Count; i++)
                        {
                            if (dgvb.Rows[i].Cells[0].Value != null && dgvb.Rows[i].Cells[0].Value.ToString() != "")
                            {
                                status = Convert.ToBoolean(dgvb.Rows[i].Cells[0].Value);
                                if (!status)
                                {
                                    cbHeader.OnChangeCheckBoxStatus(status);
                                    break;
                                }
                            }
                        }
                        if (status)
                        {
                            cbHeader.OnChangeCheckBoxStatus(status);
                        }
                        dgvb.EndEdit();
                    }
                    else
                    {
                        bool status1 = false;
                        dgvb.Rows[rowIndex].Cells[0].Value = dt.Rows[rowIndex][0].ToString();
                        for (int i = 0; i < dgvb.Rows.Count; i++)
                        {
                            if (dgvb.Rows[i].Cells[0].Value != null && dgvb.Rows[i].Cells[0].Value.ToString() != "")
                            {
                                status1 = Convert.ToBoolean(dgvb.Rows[i].Cells[0].Value);
                                if (!status1)
                                {
                                    cbHeader.OnChangeCheckBoxStatus(status1);
                                    break;
                                }
                            }
                        }
                        if (status1)
                        {
                            cbHeader.OnChangeCheckBoxStatus(status1);
                        }
                        dgvb.EndEdit();
                    }
                }
            }

        }
    }

    代码比较简单,我就没有加很多注释,也不介绍了。代码我会放在我的资源中供大家下载,资源名为:带CheckBox列头有全选择功能的DataGridView二。

        

  • 相关阅读:
    [A类会议] 国内论文检索
    [NISPA类会议] 怎样才能在NIPS 上面发论文?
    [国际A类会议] 2018最最最顶级的人工智能国际峰会汇总!CCF推荐!
    [DEFCON全球黑客大会] 针对CTF,大家都是怎么训练的?
    [DEFCON全球黑客大会] CTF(Capture The Flag)
    推荐系统之--- 评分预测问题
    推荐系统之--- 推荐系统实例
    推荐系统学习 -- 利用社交网络数据
    推荐系统学习 -- 利用上下文信息
    推荐系统学习 -- 利用用户标签数据
  • 原文地址:https://www.cnblogs.com/kevinGao/p/2776042.html
Copyright © 2011-2022 走看看