65.9K
CodeProject 正在变化。 阅读更多。
Home

DataGridView 的 CheckBox 页眉列

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (32投票s)

2007年8月24日

1分钟阅读

viewsIcon

300536

提出一种在 DataGridView 页眉中包含 CheckBox 控件的解决方案。

引言

本文将展示如何为 DataGridView 创建 CheckBoxHeaderColumn。它将暴露 CheckBoxClicked 事件,您可以在客户端应用程序中使用该事件。

背景

DataGridView 中拥有一个项目列表,并在第一列中有一个复选框是很常见的,后续操作将取决于用户的选择。可以通过将第一列定义为 DataGridViewCheckBoxCell 对象来轻松实现这一点。但是,如何让您的客户选择列表中的所有项目(假设您正在开发一个电子邮件客户端应用程序,并且用户想要删除他/她的 100 封垃圾邮件)?这是生成一个类的主要想法,该类将在表头中有一个复选框项,开发人员可以在用户检查/取消检查表头中的项目后拥有完全控制权。一个常见的操作是,根据表头是否被选中/取消选中,来选中/取消选中 DataGridView 中的所有项目。

Using the Code

整个解决方案(控件)非常简单,只包含一个类 DataGridViewCheckBoxHeaderCell

在客户端,开发人员只需要定义 DataGridViewCheckBoxColumn 并将 DataGridCheckBoxHeaderCell 分配为 HeaderCell。以下是执行此操作的代码

DataGridViewCheckBoxColumn colCB = new DataGridViewCheckBoxColumn();
DatagridViewCheckBoxHeaderCell cbHeader = new DatagridViewCheckBoxHeaderCell();
colCB.HeaderCell = cbHeader;
datagridview1.Columns.Add(colCB);

如前所述,始终用户单击表头对象中的 Checkbox 将触发 CheckboxClicked 事件,您可以在应用程序中使用该事件

cbHeader.OnCheckBoxClicked += 
    new CheckBoxClickedHandler(cbHeader_OnCheckBoxClicked);

在函数 cbHeader_OnCheckBoxClicked() 中,您可以选中/取消选中 DataGridView 的所有行,或执行任何其他操作。

这里是一个控件源

namespace TestRef
{   
    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);
        }     
    }
}

我希望这篇文章对您有所帮助,因为这是一个在我们跨数据库比较工具中用于选择数据库之间同步的行的解决方案。除此之外,您可以轻松扩展和完全自定义 CheckBox 控件的绘制,引入三态 CheckBox,并像使用普通的 CheckBox 一样进行许多其他操作。

© . All rights reserved.