zoukankan      html  css  js  c++  java
  • DataGridView中实现checkbox全选的自定义控件

    在DataGridView中实现Checkbox的全选的方法就是在列头画一个checkbox, 并给其一个事件.

    这个之前很多blog都有写, 这里就不多废话了,  codeproject上面有示例代码.

    这里我们再多做一层的封装,将其封装成一个控件,这样的话, 我们就可以最大程度上的复用, 而不需要老是重复写同样的, 无聊的代码了!

    思路如下:

    继承DataGridViewCheckBoxColumn类, 更改它的headerCell的样式. 添加cellValueChanged时间,使在进行复选框选择的时候可以触发事件,从而进行处理.

    继承DataGridViewColumnHeaderCell类, 重新绘制一个带CheckBox的HeaderCell

    话不多说直接上代码了, 如果有不懂的欢迎留言:

    public class DataGridViewCheckBoxColumnSelectAll : DataGridViewCheckBoxColumn
        {
            private DatagridViewCheckBoxHeaderCell headerCell;
            private bool loaded;
    
            public event CheckBoxClickedHandler OnCheckBoxClicked;
            int TotalCheckedCheckBoxes = 0;
            bool IsHeaderCheckBoxClicked = false;
    
            public DataGridViewCheckBoxColumnSelectAll()
            {
                this.headerCell = new DatagridViewCheckBoxHeaderCell();
                base.HeaderCell = this.headerCell;
    
                this.headerCell.OnCheckBoxClicked += new CheckBoxClickedHandler(this.headerCell_OnCheckBoxClicked);
                this.loaded = false;
               
            }
    
            public DataGridViewCheckBoxColumnSelectAll(bool threeState)
                : base(threeState)
            {
                this.headerCell = new DatagridViewCheckBoxHeaderCell();
                base.HeaderCell = this.headerCell;
            }
    
            /// <summary>
            /// 在DataGridView改变时进行事件的绑定
            /// </summary>
            protected override void OnDataGridViewChanged()
            {
                if (this.DataGridView!=null)
                {
                    this.DataGridView.CellValueChanged -= DataGridView_CellValueChanged;
                    this.DataGridView.CellValueChanged += DataGridView_CellValueChanged;
                    this.DataGridView.CurrentCellDirtyStateChanged -= DataGridView_CurrentCellDirtyStateChanged;
                    this.DataGridView.CurrentCellDirtyStateChanged += DataGridView_CurrentCellDirtyStateChanged;
                }
            }
    
            /// <summary>
            /// 在复选的时候进行判断.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            void DataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
            {
                if (e.RowIndex>=0&&e.ColumnIndex>=0)
                {
                    if (!IsHeaderCheckBoxClicked)
                        RowCheckBoxClick((DataGridViewCheckBoxCell)this.DataGridView[e.ColumnIndex, e.RowIndex]);
                }
               
            }
    
            /// <summary>
            /// 在复选框被选中的时候触发该事件, 该事件用于触发ValueChanged事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void DataGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
            {
                if (this.DataGridView.CurrentCell is DataGridViewCheckBoxCell)
                    this.DataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
            }
    
            /// <summary>
            /// 复选框被点击时所需要做的操作
            /// </summary>
            /// <param name="checkBox"></param>
            private void RowCheckBoxClick(DataGridViewCheckBoxCell checkBox)
            {
                var head = this.headerCell as DatagridViewCheckBoxHeaderCell;
                if (checkBox != null)
                {
                    //计算所有被选中的行的数量 
                    if ((bool)checkBox.Value && TotalCheckedCheckBoxes < this.DataGridView.RowCount)
                        TotalCheckedCheckBoxes++;
                    else if (TotalCheckedCheckBoxes > 0)
                        TotalCheckedCheckBoxes--;
    
                    //当所有复选框都被选中的时候,列的头上的复选框被选中, 反之则不被选中.
                    if (TotalCheckedCheckBoxes < this.DataGridView.RowCount)
                        head.IsChecked = false;
                    else if (TotalCheckedCheckBoxes == this.DataGridView.RowCount)
                        head.IsChecked = true;
                    //强制repained
                    head.DataGridView.InvalidateCell(head);
                }
            }
    
    
            /// <summary>
            /// 头被选中时触发OnCheckBoxClicked事件.
            /// </summary>
            /// <param name="state"></param>
            private void headerCell_OnCheckBoxClicked(bool state)
            {
                if (this.OnCheckBoxClicked != null)
                {
                    this.OnCheckBoxClicked(state);
                }
            }
    
        }
     public delegate void CheckBoxClickedHandler(bool state);
    
        internal class DatagridViewCheckBoxHeaderCell : DataGridViewColumnHeaderCell
        {
            private CheckBoxState _cbState = CheckBoxState.UncheckedNormal;
            private Point _cellLocation = new Point();
            private bool _checked;
            private Point checkBoxLocation;
            private Size checkBoxSize;
    
            public bool IsChecked
            {
                get
                {
                    return _checked;
                }
    
                set
                {
                    _checked = value;
                    if (this._checked)
                    {
                        this._cbState = CheckBoxState.CheckedNormal;
                    }
                    else
                    {
                        this._cbState = CheckBoxState.UncheckedNormal;
                    }
                }
            }
    
            public event CheckBoxClickedHandler OnCheckBoxClicked;
    
            /// <summary>
            /// 点击列头的时候触发的事件,这里有个判断, 如果点击的位置是复选框则触发OnCheckBoxClicked事件.
            /// </summary>
            /// <param name="e"></param>
            protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
            {
                Point point = new Point(e.X + this._cellLocation.X, e.Y + this._cellLocation.Y);
                if (((point.X >= this.checkBoxLocation.X) && (point.X <= (this.checkBoxLocation.X + this.checkBoxSize.Width))) && ((point.Y >= this.checkBoxLocation.Y) && (point.Y <= (this.checkBoxLocation.Y + this.checkBoxSize.Height))))
                {
                    this._checked = !this._checked;
                    bool temp = this._checked;
                    if (this.OnCheckBoxClicked != null)
                    {
                        this.OnCheckBoxClicked(this._checked);
                        base.DataGridView.InvalidateCell(this);
                    }
                    foreach (DataGridViewRow row in base.DataGridView.Rows)
                    {
                        ((DataGridViewCheckBoxCell)row.Cells[e.ColumnIndex]).Value = temp;
                    }
                    base.DataGridView.RefreshEdit();
    
                }
                base.OnMouseClick(e);
            }
    
            /// <summary>
            /// 绘制一个CheckBox
            /// </summary>
            protected override void Paint(Graphics graphics, Rectangle clipBounds, 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 point = new Point();
                Size glyphSize = CheckBoxRenderer.GetGlyphSize(graphics, CheckBoxState.UncheckedNormal);
                point.X = (cellBounds.Location.X + (cellBounds.Width / 2)) - (glyphSize.Width / 2);
                point.Y = (cellBounds.Location.Y + (cellBounds.Height / 2)) - (glyphSize.Height / 2);
                this._cellLocation = cellBounds.Location;
                this.checkBoxLocation = point;
                this.checkBoxSize = glyphSize;
                if (this._checked)
                {
                    this._cbState = CheckBoxState.CheckedNormal;
                }
                else
                {
                    this._cbState = CheckBoxState.UncheckedNormal;
                }
                CheckBoxRenderer.DrawCheckBox(graphics, this.checkBoxLocation, this._cbState);
            }
    
           
    
           
           
        }
    

      源码位置:

    http://pan.baidu.com/s/1jGJzErs

  • 相关阅读:
    运用Unity实现依赖注入[结合简单三层实例]
    利用WCF与Android实现图片上传并传参
    如何修改被编译后DLL文件
    ASP.NET基础之HttpHandler学习
    ASP.NET基础之HttpContext学习
    ASP.NET基础之HttpModule学习
    WCF学习笔记之事务编程
    WCF学习笔记之传输安全
    WCF心跳判断服务端及客户端是否掉线并实现重连接
    CLR_Via_C#学习笔记之事件
  • 原文地址:https://www.cnblogs.com/he-yuan/p/4300678.html
Copyright © 2011-2022 走看看