新文章 网摘 文章 随笔 日记

带行号、Checkbox列和合计的DataGridView

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

namespace UniverseSecret.Core.WinformUserControls
{
    public delegate void CheckBoxClickedHandler(DataGridViewCheckBoxHeaderCellEventArgs e);
    public class DataGridViewCheckBoxHeaderCellEventArgs : EventArgs
    {
        bool _bChecked;
        int _columnIndex;
        public DataGridViewCheckBoxHeaderCellEventArgs(bool bChecked, int columnIndex)
        {
            _bChecked = bChecked;
            _columnIndex = columnIndex;
        }
        public bool Checked
        {
            get { return _bChecked; }
        }

        public int ColumnIndex
        {
            get => _columnIndex;
        }
    }
    public 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;
        bool _drawHeaderText = true;
        public DatagridViewCheckBoxHeaderCell()
        {

        }
        public DatagridViewCheckBoxHeaderCell(bool drawHeaderText = true)
        {
            _drawHeaderText = drawHeaderText;
        }

        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, "",
                "", errorText, cellStyle,
                advancedBorderStyle, paintParts);

            Point p = new Point();

            //计算画图的起点
            Size txtSize = TextRenderer.MeasureText(formattedValue.ToString(), cellStyle.Font);
            Size s = CheckBoxRenderer.GetGlyphSize(graphics, System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);


            if (_drawHeaderText)
            {
                //画文字
                p.X = cellBounds.Location.X + (cellBounds.Width / 2) - (txtSize.Width / 2) - (s.Width / 2) - 2;
                p.Y = cellBounds.Location.Y + (cellBounds.Height / 2) - (txtSize.Height / 2);
                TextRenderer.DrawText(graphics, formattedValue.ToString(), cellStyle.Font, p, cellStyle.ForeColor);
                p.X = p.X + txtSize.Width + 2;
            }
            else
            {
                //不画文字
                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)
                {
                    var evt = new DataGridViewCheckBoxHeaderCellEventArgs(_checked, e.ColumnIndex);
                    OnCheckBoxClicked(evt);
                    this.DataGridView.InvalidateCell(this);
                }

            }
            base.OnMouseClick(e);
        }
    }




    /// <summary>
    /// 带行号、Checkbox列和合计的DataGridView
    /// </summary>
    public class DataGridViewWithSum : DataGridView
    {
        private bool _isShowSumRow = false;             //是否显示合计行
        //private string _sumCellFormat = null;           //合计单元格格式化字符串
        private int _sumRowHeight = 30;                 //合计行高
        private DataGridView _dgvSumRow = null;         //合计行
        private VScrollBar _vScrollBar = null;          //垂直滚动条
        private HScrollBar _hScrollBar = null;          //水平滚动条
        private bool _initSourceGriding = false;        //指示是否正在进行初始grid
        private DockStyle _dock;                        //Dock

        private int _dgvSourceMaxHeight = 0;            //dgvSource最大高度
        private int _dgvSourceMaxWidth = 0;             //dgvSource最大宽度

        private int _marginLeft = 0;
        private int _marginTop = 0;
        private int _marginRight = 0;
        private int _marginBottom = 0;

        private Dictionary<string, string> _sumColumns;

        /// <summary>
        /// checkbox列
        /// </summary>
        private Dictionary<string, bool> _checkboxColumns = new Dictionary<string, bool>();

        public DataGridViewWithSum()
        {
            base.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.ColumnWidthChanged += new DataGridViewColumnEventHandler(this_ColumnWidthChanged);
            this.ParentChanged += DataGridViewWithSum_ParentChanged;

            this.RowHeadersWidthChanged += new EventHandler(this_RowHeadersWidthChanged);
            this.MouseWheel += new MouseEventHandler(dgvSource_MouseWheel);
            this.DataSourceChanged += DataGridViewWithSum_DataSourceChanged;
            this.CellEndEdit += DataGridViewWithSum_CellEndEdit;
            this.RowPostPaint += DataGridViewWithSum_RowPostPaint;
            this.CellContentClick += DataGridViewWithSum_CellContentClick;
        }

        private void DataGridViewWithSum_DataSourceChanged(object sender, EventArgs e)
        {
            SumData();
        }


        /// <summary>
        /// 在左边画行号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DataGridViewWithSum_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(
                    e.RowBounds.Location.X,
                    e.RowBounds.Location.Y,
                    this.RowHeadersWidth - 4,
                    e.RowBounds.Height);

            TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(),
                this.RowHeadersDefaultCellStyle.Font,
                rectangle,
                this.RowHeadersDefaultCellStyle.ForeColor,
                TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
        }

        private void DataGridViewWithSum_ParentChanged(object sender, EventArgs e)
        {
            _marginLeft = this.Left;
            _marginTop = this.Top;
            _marginRight = this.Parent.Width - this.Right;
            _marginBottom = this.Parent.Height - this.Bottom;

            this.Parent.SizeChanged += Parent_SizeChanged;
        }

        private void Parent_SizeChanged(object sender, EventArgs e)
        {
            _dgvSourceMaxHeight = this.Parent.Height - _marginTop - _marginBottom;
            _dgvSourceMaxWidth = this.Parent.Width - _marginLeft - _marginRight;

            if (!_initSourceGriding)
            {
                InitScrollWithSourceGrid();
                this.Update();
            }

        }

        private void DataGridViewWithSum_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            IsShowHScrollBar();
            IsShowVScrollBar();
        }

        private void DataGridViewWithSum_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            SumData();
        }


        /// <summary>
        /// 初始化合计行
        /// </summary>
        private void InitSumRowDgv()
        {
            _dgvSumRow = new DataGridView();


            _dgvSumRow.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;

            _dgvSumRow.BackgroundColor = this.BackgroundColor;
            _dgvSumRow.ColumnHeadersVisible = false;
            _dgvSumRow.AllowUserToResizeColumns = false;
            _dgvSumRow.AllowUserToResizeRows = false;
            _dgvSumRow.ScrollBars = System.Windows.Forms.ScrollBars.None;
            _dgvSumRow.Visible = false;
            _dgvSumRow.Height = _sumRowHeight;
            _dgvSumRow.RowTemplate.Height = _sumRowHeight;
            _dgvSumRow.AllowUserToAddRows = false;
            _dgvSumRow.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
            _dgvSumRow.ReadOnly = true;
            _dgvSumRow.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            _dgvSumRow.DefaultCellStyle.SelectionBackColor = _dgvSumRow.DefaultCellStyle.BackColor;
            _dgvSumRow.DefaultCellStyle.SelectionForeColor = _dgvSumRow.DefaultCellStyle.ForeColor;
            _dgvSumRow.Font = new Font("宋体", 10, FontStyle.Bold);
            _dgvSumRow.RowPostPaint += new DataGridViewRowPostPaintEventHandler(dgvSumRow_RowPostPaint);
        }

        /// <summary>
        /// 初始化合计dgv及滚动条
        /// </summary>
        private void InitSumDgvAndScrolBar()
        {
            if (this.Parent == null)
            {
                return;
            }

            //滚动条
            _vScrollBar = new VScrollBar();
            _hScrollBar = new HScrollBar();
            if (DesignMode)
            {
                base.ScrollBars = System.Windows.Forms.ScrollBars.Both;
            }
            else
            {
                this.ScrollBars = ScrollBars.None;         //禁用dgv默认滚动条
            }
            this.Parent.Controls.Add(_vScrollBar);
            this.Parent.Controls.Add(_hScrollBar);

            _vScrollBar.Visible = false;
            _hScrollBar.Visible = false;

            //注册滚动条事件已代替dgv默认的滚动条
            _vScrollBar.Scroll += new ScrollEventHandler(vScrollBar_Scroll);
            _hScrollBar.Scroll += new ScrollEventHandler(hScrollBar_Scroll);
            InitSumRowDgv();
            this.Parent.Controls.Add(_dgvSumRow);



            this.SizeChanged += (s, e) =>
            {
                if (!_initSourceGriding)
                {
                    InitScrollWithSourceGrid();
                    this.Update();
                }
            };
        }
        /// <summary>
        /// 根据源Grid设置是否需展示滚动条
        /// </summary>
        private void InitScrollWithSourceGrid()
        {
            if (_initSourceGriding || this.Parent == null)
            {
                return;
            }

            //初始化合计行
            if (_dgvSumRow == null)
            {
                InitSumDgvAndScrolBar();
            }
            _initSourceGriding = true;

            if (_dock == DockStyle.Fill)
            {
                this.Height = Parent.Height;
                this.Width = Parent.Width;
                this.Location = new Point(0, 0);
            }

            if (_isShowSumRow)
            {
                if (_hScrollBar != null && _hScrollBar.Visible)
                {
                    this.Height = _dgvSourceMaxHeight - _sumRowHeight - _hScrollBar.Height;
                }
                else
                {
                    this.Height = _dgvSourceMaxHeight - _sumRowHeight;
                }
            }
            if (this.Height < RowHeight * 2)
            {
                _initSourceGriding = false;
                return;
            }

            IsShowHScrollBar();

            //根据源dgv设置合计行
            _dgvSumRow.RowHeadersWidth = this.RowHeadersWidth - 1;

            IsShowVScrollBar();

            if (_isShowSumRow && !DesignMode)
            {
                _dgvSumRow.Location = new Point(this.Location.X, this.Location.Y + this.Height - 1);
                _dgvSumRow.Width = this.Width;
                _dgvSumRow.Visible = true;
                _dgvSumRow.BringToFront();
            }
            else
            {
                _dgvSumRow.Visible = false;
            }
            _initSourceGriding = false;

            this.RowsAdded += DataGridViewWithSum_RowsAdded;
        }
        /// <summary>
        /// 验证是否需要显示纵向滚动条
        /// </summary>
        private void IsShowVScrollBar()
        {
            var dgvSourceDisplayedRowCount = this.DisplayedRowCount(false);     //最多显示行数
            bool show = dgvSourceDisplayedRowCount < this.Rows.Count;


            //不需要展示垂直滚动条
            if (!show)
            {
                _vScrollBar.Visible = false;
                this.Width = _dgvSourceMaxWidth;
                _dgvSumRow.Width = _dgvSourceMaxWidth;
            }
            else
            {
                //需要展示垂直滚动条
                this.Width = _dgvSourceMaxWidth - _vScrollBar.Width;
                _vScrollBar.Height = this.Height + (_isShowSumRow ? _dgvSumRow.Height : 0);
                _vScrollBar.Location = new Point(this.Location.X + this.Width, this.Location.Y);
                _vScrollBar.Visible = true;
                _vScrollBar.Maximum = (this.Rows.Count - dgvSourceDisplayedRowCount + 2) * RowHeight;
                _vScrollBar.Minimum = 0;
                _vScrollBar.SmallChange = RowHeight;
                _vScrollBar.LargeChange = RowHeight * 2;
                _vScrollBar.BringToFront();
            }
        }
        /// <summary>
        /// 验证是否需要显示水平滚动条
        /// </summary>
        private void IsShowHScrollBar()
        {
            var displayDgvSumRowHeight = (_isShowSumRow && !DesignMode) ? _dgvSumRow.Height : 0;

            //需要展示水平滚动条
            if (this.DisplayedColumnCount(true) < this.Columns.Count)
            {
                if (IsShowSumRow)
                {
                    this.Height = _dgvSourceMaxHeight - _hScrollBar.Height - _dgvSumRow.Height;

                }
                else
                {
                    this.Height = _dgvSourceMaxHeight - _hScrollBar.Height;
                }

                _hScrollBar.Location = new Point(this.Location.X, this.Location.Y + this.Height + displayDgvSumRowHeight);
                _hScrollBar.Width = _dgvSourceMaxWidth;
                _hScrollBar.Visible = true;
                _hScrollBar.BringToFront();
                _hScrollBar.Minimum = 0;
                _hScrollBar.SmallChange = AvgColWidth;
                _hScrollBar.LargeChange = AvgColWidth * 2;
                _hScrollBar.Maximum = ColsWidth;
            }
            else
            {
                _hScrollBar.Visible = false;
                if (IsShowSumRow)
                {
                    this.Height = _dgvSourceMaxHeight - _dgvSumRow.Height;
                }
                else
                {
                    this.Height = _dgvSourceMaxHeight;
                }
            }
        }
        /// <summary>
        /// DataGridView 列总宽.用于确定横向滚动条滚动值
        /// </summary>
        private int ColsWidth
        {
            get
            {
                int width = 0;
                foreach (DataGridViewColumn col in this.Columns)
                {
                    if (!col.Visible)
                    {
                        continue;
                    }
                    width += col.Width;
                }
                return width;
            }
        }

        /// <summary>
        /// DataGridView 列平均总宽,用于确定横向滚动条滚动值
        /// </summary>
        private int AvgColWidth
        {
            get
            {
                int width = 80;
                width = ColsWidth / this.Columns.Count;
                return width;
            }
        }

        /// <summary>
        /// 每行高度.用于确定纵向滚动条滚动值
        /// </summary>
        private int RowHeight
        {
            get
            {
                int height = 20;
                if (this.Rows.Count > 0)
                {
                    height = (this.Rows[0].Height - 3);
                }
                return height;
            }
        }

        /// <summary>
        /// 处理纵向滚动条事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void vScrollBar_Scroll(object sender, ScrollEventArgs e)
        {
            this.FirstDisplayedScrollingRowIndex = e.NewValue / RowHeight;
        }

        /// <summary>
        /// 处理横向滚动条事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void hScrollBar_Scroll(object sender, ScrollEventArgs e)
        {
            int value = e.NewValue;
            this.HorizontalScrollingOffset = value;

            if (_isShowSumRow && _dgvSumRow != null)
            {
                _dgvSumRow.HorizontalScrollingOffset = value;
            }
        }

        /// <summary>
        /// 处理源dgv鼠标滚轮滚动事件,同步带动横向滚动条及纵向滚动条
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvSource_MouseWheel(object sender, MouseEventArgs e)
        {
            if (!_vScrollBar.Visible) return;

            if ((_vScrollBar.Value - RowHeight) < 0 && e.Delta > 0)
            {
                _vScrollBar.Value = _vScrollBar.Minimum;
            }
            else if ((_vScrollBar.Value + RowHeight * 2) > _vScrollBar.Maximum && e.Delta < 0)
            {
                _vScrollBar.Value = _vScrollBar.Maximum;
            }
            else
            {
                _vScrollBar.Value -= Convert.ToInt32((e.Delta / Math.Abs(e.Delta))) * RowHeight;
            }
            this.FirstDisplayedScrollingRowIndex = _vScrollBar.Value / RowHeight;
        }

        private void this_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
        {
            if (_dgvSumRow != null && _dgvSumRow.Columns != null && _dgvSumRow.Columns.Count > 0)
            {
                _dgvSumRow.Columns[e.Column.Index].Width = e.Column.Width;
            }
        }

        private void this_RowHeadersWidthChanged(object sender, EventArgs e)
        {
            if (_dgvSumRow != null)
            {
                _dgvSumRow.RowHeadersWidth = this.RowHeadersWidth - 1;
            }
        }



        /// <summary>
        /// 获取或设置需要用于求和的列名
        /// </summary>
        /// <param name="columnName"></param>
        /// <param name="dataFormat"></param>
        [Description("获取或设置需要用于求和的列名")]
        public void AddSumColumn(string columnName, string dataFormat)
        {
            _sumColumns.Add(columnName, dataFormat);
        }

        /// <summary>
        /// 合计数据
        /// </summary>
        private void SumData()
        {
            if (this.Columns.Count <= 0)
            {
                return;
            }

            if (_dgvSumRow.Columns.Count != this.Columns.Count)
            {
                AddDgvSumRowColumns();
            }

            if (_dgvSumRow.Rows.Count != 1)
            {
                _dgvSumRow.Rows.Clear();
                _dgvSumRow.Rows.Add(1);
            }

            if (this.Rows.Count <= 0 || _sumColumns == null || _sumColumns.Count == 0)
            {
                return;
            }

            var sumRowDataDic = new Dictionary<int, decimal>();

            #region 按设置的需要合计的列求和
            foreach (var col in _sumColumns)
            {
                if (!_dgvSumRow.Columns.Contains(col.Key))
                {
                    return;
                }
                var tempSumVal = 0m;
                var colIndex = _dgvSumRow.Columns[col.Key].Index;
                for (int i = 0; i < this.Rows.Count; i++)
                {
                    if (this[colIndex, i].Value == null)
                    {
                        continue;
                    }

                    var tempVal = 0m;
                    try
                    {
                        tempVal = (decimal)Convert.ChangeType(this[colIndex, i].Value, typeof(decimal));
                    }
                    catch { }
                    tempSumVal += tempVal;
                }
                sumRowDataDic[colIndex] = tempSumVal;
            }

            #endregion

            if (sumRowDataDic.Count > 0)
            {
                sumRowDataDic.Keys.ToList().ForEach(colIndex =>
                {
                    _dgvSumRow[colIndex, 0].Value = sumRowDataDic[colIndex];
                });
            }
        }

        /// <summary>
        /// 获取合计行
        /// </summary>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public DataGridViewRow SumRow
        {
            get
            {
                return (_isShowSumRow && _dgvSumRow.Rows.Count > 0) ? _dgvSumRow.Rows[0] : null;
            }
        }
        private void this_DataSourceChanged(object sender, EventArgs e)
        {
            SumData();
        }

        /// <summary>
        /// 绘制合计行行头
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvSumRow_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            var rectangle = new Rectangle(e.RowBounds.Location.X + 1, e.RowBounds.Location.Y + 1,
                _dgvSumRow.RowHeadersWidth - 3, e.RowBounds.Height - 3);

            e.Graphics.FillRectangle(new SolidBrush(_dgvSumRow.RowHeadersDefaultCellStyle.BackColor), rectangle);

            TextRenderer.DrawText(e.Graphics, "合计",
                _dgvSumRow.RowHeadersDefaultCellStyle.Font,
                rectangle,
                _dgvSumRow.RowHeadersDefaultCellStyle.ForeColor,
                TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter);
        }

        /// <summary>
        /// 获取或设置Dock,该属性已被重新
        /// </summary>
        [Description("获取或设置Dock,该属性已被重写")]
        public new DockStyle Dock
        {
            get { return _dock; }
            set
            {
                _dock = value;
                if (value == DockStyle.Fill)
                {
                    if (Parent != null)
                    {
                        this.Size = new Size(Parent.Width, Parent.Height);
                        this.Location = new Point(0, 0);
                    }
                    this.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
                }
                else
                {
                    this.Height = Parent.Height - 20;
                    this.Width = Parent.Width - 20;
                }
            }
        }

        /// <summary>
        /// BorderStyle属性已被重写,该值固定为None,设置无效
        /// </summary>
        [Description("BorderStyle属性已被重写,该值固定为None,设置无效")]
        public new BorderStyle BorderStyle
        {
            get { return System.Windows.Forms.BorderStyle.None; }
            set { }
        }

        ///// <summary>
        ///// 获取或设置合计行单元格格式化字符串
        ///// </summary>
        //[Description("获取或设置合计行单元格格式化字符串")]
        //public string SumRowCellFormat
        //{
        //    get { return _sumCellFormat; }
        //    set { _sumCellFormat = value; }
        //}

        /// <summary>
        /// 获取或设置是否显示合计行
        /// </summary>
        [Description("获取或设置是否显示合计行")]
        public bool IsShowSumRow
        {
            get { return _isShowSumRow; }
            set
            {
                _isShowSumRow = value;
                _sumColumns = new Dictionary<string, string>();
                InitScrollWithSourceGrid();
            }
        }

        private void AddDgvSumRowColumns()
        {
            if (_dgvSumRow.Columns.Count == 0)
            {
                foreach (DataGridViewColumn col in this.Columns)
                {
                    var tempCol = (DataGridViewColumn)col.Clone();
                    tempCol.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                    if (_sumColumns.ContainsKey( col.Name))
                    {
                        tempCol.DefaultCellStyle.Format = _sumColumns[col.Name];
                    }
                    _dgvSumRow.Columns.Add(tempCol);
                }
            }
        }


        #region 添加checkBox列

        /// <summary>
        /// 插入CheckBox列
        /// </summary>
        /// <param name="columnIndex">在columnIndex列前插入</param>
        /// <param name="headerText">CheckBox列的名称</param>
        /// <param name="dataPropertyName">CheckBox列对应的数据字段名</param>
        /// <param name="multiple">是否多选</param>


        public void InsertCheckBoxColumn(int columnIndex, string headerText, string dataPropertyName, bool multiple)
        {
            if (_checkboxColumns.ContainsKey(dataPropertyName))
            {
                return;
            }

            _checkboxColumns.Add(dataPropertyName, multiple);
            DataGridViewCheckBoxColumn columncb = new DataGridViewCheckBoxColumn()
            {
                Name = dataPropertyName,
                TrueValue = true,
                FalseValue = false,
                DataPropertyName = dataPropertyName,
                HeaderText = headerText
            };


            //如果多选,则添加全选按钮
            if (multiple)
            {
                DatagridViewCheckBoxHeaderCell cbHeader = new DatagridViewCheckBoxHeaderCell();
                cbHeader.OnCheckBoxClicked += CbHeader_OnCheckBoxClicked;
                columncb.HeaderCell = cbHeader;
            }


            //解除冻结
            List<string> frozenColumns = new List<string>();
            for (int i = 0; i < this.Columns.Count; i++)
            {
                if (Columns[i].Frozen)
                {
                    frozenColumns.Add(Columns[i].Name);
                    Columns[i].Frozen = false;
                }
            }
            //插入CheckBox列
            this.Columns.Insert(columnIndex, columncb);

            //重新冻结
            foreach (var item in frozenColumns)
            {
                Columns[item].Frozen = true;
            }
        }

        private void CbHeader_OnCheckBoxClicked(DataGridViewCheckBoxHeaderCellEventArgs e)
        {
            SetAllRowChecked(e.ColumnIndex, e.Checked);
        }


        /// <summary>
        /// 设置全选或全不选
        /// </summary>
        private void SetAllRowChecked(int columnIndex, bool status)
        {
            //这一句很重要结束编辑状态
            this.EndEdit();
            this.Rows.OfType<DataGridViewRow>().ToList().ForEach(t => t.Cells[columnIndex].Value = status);
        }



        /// <summary>
        /// 获取选定的行的指定列的值
        /// </summary>
        /// <param name="checkBoxColumnName"></param>
        /// <param name="columnNameToGetValue"></param>
        /// <returns></returns>
        public List<object> GetCheckedItems(string checkBoxColumnName, string columnNameToGetValue)
        {
            //这一句很重要结束编辑状态
            this.EndEdit();

            List<object> checkedItems = new List<object>();
            int count = Convert.ToInt32(this.Rows.Count.ToString());
            for (int i = 0; i < count; i++)
            {
                if (Rows[i].IsNewRow)
                {
                    continue;
                }
                bool flag = GetCheckBoxValue(i, checkBoxColumnName);
                if (flag) //查找被选择的数据行
                {
                    checkedItems.Add(this.Rows[i].Cells[columnNameToGetValue].Value);
                }
            }
            return checkedItems;
        }
        public bool GetCheckBoxValue(int rowIndex, string checkBoxColumnName)
        {
            //这一句很重要结束编辑状态
            this.EndEdit();
            DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)this.Rows[rowIndex].Cells[checkBoxColumnName];
            bool value = Convert.ToBoolean(checkCell.Value);
            return value;
        }
        private bool GetCheckBoxValue(int rowIndex, int checkBoxColumnIndex)
        {
            //这一句很重要结束编辑状态
            this.EndEdit();
            DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)this.Rows[rowIndex].Cells[checkBoxColumnIndex];
            bool value = Convert.ToBoolean(checkCell.Value);
            return value;
        }

        /// <summary>
        /// 表格单元点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DataGridViewWithSum_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex == -1)
            {
                return;
            }
            var columnName = this.Columns[e.ColumnIndex].Name;
            if (!_checkboxColumns.ContainsKey(columnName))
            {
                return;
            }

            //如果是单选
            if (!_checkboxColumns[columnName])
            {
                var value = GetCheckBoxValue(e.RowIndex, e.ColumnIndex);
                SetAllRowChecked(e.ColumnIndex, false);
                Check(e.RowIndex, e.ColumnIndex, value);
            }
        }
        private void Check(int rowIndex, int columnIndex, bool value)
        {
            //这一句很重要结束编辑状态
            this.EndEdit();
            //获取控件的值
            DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)this.Rows[rowIndex].Cells[columnIndex];
            checkCell.Value = value;
        }
        #endregion
    }
}

 

posted @ 2021-07-22 17:04  岭南春  阅读(104)  评论(0)    收藏  举报