c# datagridview列头添加复选框实现全选

来源:互联网 发布:淘宝自行车头盔 编辑:程序博客网 时间:2024/05/20 11:52


1.datagridview列头添加复选框
    网上查了很多资料,大都是通过添加自绘复选框类来实现的。经验证效果不错。

/*****************************以下是自定义在datagridview列头绘制复选框*********************************************/    //定义继承于DataGridViewColumnHeaderCell的类,用于绘制checkbox,定义checkbox鼠标单击事件    public class datagridviewCheckboxHeaderCell : DataGridViewColumnHeaderCell    {        public delegate void HeaderEventHander(object sender, datagridviewCheckboxHeaderEventArgs e);        public event HeaderEventHander OnCheckBoxClicked;        Point checkBoxLocation;        Size checkBoxSize;        bool _checked = false;        Point _cellLocation = new Point();        System.Windows.Forms.VisualStyles.CheckBoxState _cbState =            System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal;        //绘制列头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)        {            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;                //获取列头checkbox的选择状态                datagridviewCheckboxHeaderEventArgs ex = new datagridviewCheckboxHeaderEventArgs();                ex.CheckedState = _checked;                object sender = new object();//此处不代表选择的列头checkbox,只是作为参数传递。应该列头checkbox是绘制出来的,无法获得它的实例                if (OnCheckBoxClicked != null)                {                    OnCheckBoxClicked(sender, ex);//触发单击事件                    this.DataGridView.InvalidateCell(this);                }            }            base.OnMouseClick(e);        }    }    public class datagridviewCheckboxHeaderEventArgs : EventArgs    {        private bool checkedState = false;        public bool CheckedState        {            get { return checkedState; }            set { checkedState = value; }        }    }

自己的程序里代码如下

//定义触发单击事件的委托               public delegate void datagridviewcheckboxHeaderEventHander(object sender, datagridviewCheckboxHeaderEventArgs e);        void ch_OnCheckBoxClicked(object sender, datagridviewCheckboxHeaderEventArgs e)         {            foreach (DataGridViewRow dgvRow in dataGridView_BarcodeMerge.Rows)             {                if (e.CheckedState)                {                    dgvRow.Cells[0].Value = true;                 }                 else                 {                    dgvRow.Cells[0].Value = false;                 }            }         }        private DataTable CreateDataTable()        {            DataTable dt = new DataTable();            dt.Columns.Add("是否选择", System.Type.GetType("System.Boolean"));            dt.Columns.Add(new DataColumn("标号"));            dt.Columns.Add(new DataColumn("客户"));            dt.Columns.Add(new DataColumn("类别"));            dt.Columns.Add(new DataColumn("序号"));            dt.Columns.Add(new DataColumn("零件名称"));            dt.Columns.Add(new DataColumn("图号/规格"));            dt.Columns.Add(new DataColumn("版本"));            dt.Columns.Add(new DataColumn("数量"));            dt.Columns.Add(new DataColumn("加工商"));            dt.Columns.Add(new DataColumn("条码号"));            return dt;        }

datagridview绑定数据源的时候代码如下:

private void button_Query_Click(object sender, EventArgs e)//查询        {            foreach (var task in TaskGroup)            {                  DataTable dt = CreateDataTable();                dt.Rows.Add(new object[] { false, task.TaskID, task.customerName, task.ComponentCategory, task.Number, task.ComponentName, task.FigureNo_Spec, task.Version, task.Quantity, task.supplierName, task.Barcodes });                dataGridView_BarcodeMerge.DataSource = dt;dataGridView_BarcodeMerge.AllowUserToAddRows = false;//解决用户点击复选框,表格自动增加一行                datagridviewCheckboxHeaderCell ch = new datagridviewCheckboxHeaderCell();                ch.OnCheckBoxClicked += new datagridviewCheckboxHeaderCell.HeaderEventHander(ch_OnCheckBoxClicked);                DataGridViewCheckBoxColumn checkboxCol = dataGridView_BarcodeMerge.Columns["是否选择"] as DataGridViewCheckBoxColumn;                checkboxCol.HeaderCell = ch;                checkboxCol.HeaderCell.Value = "全选";//消除列头checkbox旁出现的文字            }        }


2.全选
    当datagridview某行选中时,点击全选复选框,该行是没有反应的。这是因为该行处于编辑状态,无法获取该行的值。
    解决方法,结束编辑状态。选择datagridview的CellContentClick事件,添加代码

private void dataGridView_BarcodeMerge_CellContentClick(object sender, DataGridViewCellEventArgs e)        {            if (e.RowIndex != -1 && e.ColumnIndex == 0)            {                dataGridView_BarcodeMerge.EndEdit();            }        }

这样就可以实现全选,取消全选了。
引用了某些博客的文章,忘了出处了。相关博客者看到了希望不要介意。。。




0 0