Skip to content

Instantly share code, notes, and snippets.

@KOZ60
Last active May 29, 2024 09:14
Show Gist options
  • Save KOZ60/bf90763ff79e178c66844c8cd7c11a14 to your computer and use it in GitHub Desktop.
Save KOZ60/bf90763ff79e178c66844c8cd7c11a14 to your computer and use it in GitHub Desktop.
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
public class DataGridViewSelectAllCheckBoxHeaderCell : DataGridViewColumnHeaderCell
{
protected static class CheckBoxHeaderCellRenderer
{
private static readonly VisualStyleElement CheckBoxElement
= VisualStyleElement.Button.CheckBox.UncheckedNormal;
[ThreadStatic]
static VisualStyleRenderer visualStyleRenderer;
public static VisualStyleRenderer CheckBoxRenderer {
get {
if (visualStyleRenderer == null) {
visualStyleRenderer = new VisualStyleRenderer(CheckBoxElement);
}
return visualStyleRenderer;
}
}
public static void DrawCheckBox(Graphics g, Rectangle bounds, CheckBoxState state) {
CheckBoxRenderer.SetParameters(CheckBoxElement.ClassName, CheckBoxElement.Part, (int)state);
CheckBoxRenderer.DrawBackground(g, bounds, Rectangle.Truncate(g.ClipBounds));
}
}
private DataGridView _Owner;
private CheckState? _AllCheckState = null;
private int allCheckStateChangingCount = 0;
private bool _MouseIsDown;
private bool _MouseIsOver;
public DataGridViewSelectAllCheckBoxHeaderCell() {
// For GetContentBounds
Value = " ";
}
protected void Invalidate() {
if (Owner != null && Owner.IsHandleCreated) {
Owner.InvalidateCell(ColumnIndex, -1);
}
}
protected override void OnDataGridViewChanged() {
base.OnDataGridViewChanged();
Owner = DataGridView;
}
protected DataGridView Owner {
get {
return _Owner;
}
set {
if (_Owner != null) {
_Owner.CurrentCellDirtyStateChanged -= Owner_CurrentCellDirtyStateChanged;
_Owner.CellValueChanged -= Owner_CellValueChanged;
_Owner.RowsAdded -= Owner_RowsAdded;
_Owner.RowsRemoved -= Owner_RowsRemoved;
_Owner.DataError -= Owner_DataError;
}
_Owner = value;
if (_Owner != null) {
_Owner.CurrentCellDirtyStateChanged += Owner_CurrentCellDirtyStateChanged;
_Owner.CellValueChanged += Owner_CellValueChanged;
_Owner.RowsAdded += Owner_RowsAdded;
_Owner.RowsRemoved += Owner_RowsRemoved;
_Owner.DataError += Owner_DataError;
}
}
}
protected DataGridViewCheckBoxColumn OwnerColumn {
get {
if (Owner != null) {
return Owner.Columns[ColumnIndex] as DataGridViewCheckBoxColumn;
}
return null;
}
}
private void Owner_CurrentCellDirtyStateChanged(object sender, EventArgs e) {
OnCurrentCellDirtyStateChanged(e);
}
private void Owner_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
OnCellValueChanged(e);
}
private void Owner_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e) {
OnRowsRemoved(e);
}
private void Owner_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e) {
OnRowsAdded(e);
}
private void Owner_DataError(object sender, DataGridViewDataErrorEventArgs e) {
OnDataError(e);
}
protected virtual void OnCurrentCellDirtyStateChanged(EventArgs e) {
if (Owner.IsCurrentCellDirty &&
Owner.CurrentCell.ColumnIndex == ColumnIndex) {
Owner.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
protected virtual void OnCellValueChanged(DataGridViewCellEventArgs e) {
if (e.ColumnIndex == ColumnIndex && !AllCheckStateChanging) {
ResetState();
}
}
protected virtual void OnRowsRemoved(DataGridViewRowsRemovedEventArgs e) {
ResetState();
}
protected virtual void OnRowsAdded(DataGridViewRowsAddedEventArgs e) {
ResetState();
}
protected virtual void OnDataError(DataGridViewDataErrorEventArgs e) {
if (e.ColumnIndex == ColumnIndex) {
e.ThrowException = false;
}
}
protected void ResetState() {
_AllCheckState = null;
Invalidate();
}
protected int CommittedRowCount {
get {
int rowCount = Owner.RowCount;
if (rowCount > 0) {
if (Owner.Rows[rowCount - 1].IsNewRow) {
return rowCount - 1;
} else {
return rowCount;
}
} else {
return 0;
}
}
}
protected virtual CheckState AllCheckState {
get {
if (_AllCheckState.HasValue) {
return _AllCheckState.Value;
}
int checkedCount = 0;
int rowCount = CommittedRowCount;
if (rowCount > 0) {
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
object value = Owner[ColumnIndex, rowIndex].FormattedValue;
if (value != null) {
if (value is CheckState state) {
switch (state) {
case CheckState.Checked:
checkedCount++;
break;
case CheckState.Indeterminate:
return CheckState.Indeterminate;
}
}
if (value is bool bChecked && bChecked) {
checkedCount++;
}
}
}
if (checkedCount == 0) {
_AllCheckState = CheckState.Unchecked;
} else if (checkedCount == rowCount) {
_AllCheckState = CheckState.Checked;
} else {
_AllCheckState = CheckState.Indeterminate;
}
} else {
_AllCheckState = CheckState.Unchecked;
}
return _AllCheckState.Value;
}
set {
if (AllCheckState != value) {
switch (value) {
case CheckState.Checked:
case CheckState.Unchecked:
object setValue;
if (OwnerColumn.ThreeState) {
if (value == CheckState.Checked) {
setValue = OwnerColumn.TrueValue ?? CheckState.Checked;
} else {
setValue = OwnerColumn.FalseValue ?? CheckState.Unchecked;
}
} else {
if (value == CheckState.Checked) {
setValue = OwnerColumn.TrueValue ?? true;
} else {
setValue = OwnerColumn.FalseValue ?? false;
}
}
AllCheckStateChanging = true;
try {
int rowCount = CommittedRowCount;
if (Owner.IsCurrentCellInEditMode) {
Owner.EndEdit();
}
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
Owner[ColumnIndex, rowIndex].Value = setValue;
}
} finally {
AllCheckStateChanging = false;
}
break;
}
_AllCheckState = value;
Invalidate();
}
}
}
protected bool AllCheckStateChanging {
get {
return allCheckStateChangingCount > 0;
}
set {
if (value) {
allCheckStateChangingCount++;
} else {
if (allCheckStateChangingCount > 0) {
allCheckStateChangingCount--;
}
}
}
}
protected virtual Rectangle ClickRectangle {
get {
using (var g = Owner.CreateGraphics()) {
return GetContentBounds(g, OwnerColumn.InheritedStyle, -1);
}
}
}
protected bool MouseIsDown {
get { return _MouseIsDown; }
set {
if (MouseIsDown != value) {
_MouseIsDown = value;
Invalidate();
}
}
}
protected bool MouseIsOver {
get { return _MouseIsOver; }
set {
if (MouseIsOver != value) {
_MouseIsOver = value;
Invalidate();
}
}
}
protected override void OnMouseEnter(int rowIndex) {
base.OnMouseEnter(rowIndex);
var mouseLocation = Owner.PointToClient(Control.MousePosition);
MouseIsOver = ClickRectangle.Contains(mouseLocation.X, mouseLocation.Y);
}
protected override void OnMouseLeave(int rowIndex) {
base.OnMouseLeave(rowIndex);
MouseIsOver = false;
MouseIsDown = false;
}
protected override void OnMouseMove(DataGridViewCellMouseEventArgs e) {
base.OnMouseMove(e);
MouseIsOver = ClickRectangle.Contains(e.X, e.Y);
}
protected override void OnMouseDown(DataGridViewCellMouseEventArgs e) {
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left && ClickRectangle.Contains(e.X, e.Y)) {
MouseIsDown = true;
}
}
protected override void OnMouseUp(DataGridViewCellMouseEventArgs e) {
base.OnMouseUp(e);
if (e.Button == MouseButtons.Left &&
!OwnerColumn.ReadOnly &&
ClickRectangle.Contains(e.X, e.Y) &&
MouseIsDown) {
if (CommittedRowCount > 0) {
if (AllCheckState == CheckState.Unchecked) {
AllCheckState = CheckState.Checked;
} else {
AllCheckState = CheckState.Unchecked;
}
} else {
AllCheckState = CheckState.Unchecked;
}
}
MouseIsDown = false;
}
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, string.Empty, string.Empty, errorText, cellStyle, advancedBorderStyle, paintParts);
Rectangle checkBoxBounds = GetCheckBoxBounds(graphics, cellBounds,
advancedBorderStyle, CheckBoxState.UncheckedNormal);
CheckBoxState checkBoxState = GetCheckBoxState();
DrawCheckBox(graphics, checkBoxBounds, checkBoxState);
}
protected virtual void DrawCheckBox(Graphics g, Rectangle checkBoxBounds, CheckBoxState checkBoxState) {
if (Application.RenderWithVisualStyles) {
CheckBoxHeaderCellRenderer.DrawCheckBox(g, checkBoxBounds, checkBoxState);
} else {
ButtonState bs = ToButtonState(checkBoxState);
if (IsMixDraw(checkBoxState)) {
ControlPaint.DrawMixedCheckBox(g, checkBoxBounds, bs);
} else {
ControlPaint.DrawCheckBox(g, checkBoxBounds, bs);
}
}
}
protected virtual ButtonState ToButtonState(CheckBoxState checkBoxState) {
ButtonState bs;
switch (checkBoxState) {
case CheckBoxState.UncheckedNormal:
case CheckBoxState.UncheckedHot:
case CheckBoxState.UncheckedPressed:
case CheckBoxState.UncheckedDisabled:
bs = ButtonState.Normal;
break;
case CheckBoxState.CheckedNormal:
case CheckBoxState.CheckedHot:
case CheckBoxState.CheckedPressed:
case CheckBoxState.CheckedDisabled:
bs = ButtonState.Checked;
break;
default:
bs = ButtonState.Inactive;
break;
}
switch (checkBoxState) {
case CheckBoxState.UncheckedPressed:
case CheckBoxState.CheckedPressed:
case CheckBoxState.MixedPressed:
bs |= ButtonState.Pushed;
break;
}
return bs;
}
protected virtual bool IsMixDraw(CheckBoxState checkBoxState) {
switch (checkBoxState) {
case CheckBoxState.MixedNormal:
case CheckBoxState.MixedHot:
case CheckBoxState.MixedPressed:
case CheckBoxState.MixedDisabled:
return true;
}
return false;
}
protected virtual CheckBoxState GetCheckBoxState() {
if (OwnerColumn.ReadOnly) {
return CheckBoxState.MixedDisabled;
} else {
if (MouseIsDown) {
return CheckBoxState.UncheckedPressed;
} else {
switch (AllCheckState) {
case CheckState.Checked:
return CheckBoxState.CheckedNormal;
case CheckState.Unchecked:
return CheckBoxState.UncheckedNormal;
default:
return CheckBoxState.MixedNormal;
}
}
}
}
protected virtual Rectangle GetCheckBoxBounds(Graphics g, Rectangle cellBounds,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
CheckBoxState state) {
Size checkBoxSize = GetCheckBoxSize(g, state);
Rectangle valBounds = cellBounds;
valBounds.Width -= 1;
Rectangle borderWidths = BorderWidths(advancedBorderStyle);
valBounds.Offset(borderWidths.X, borderWidths.Y);
valBounds.Width -= borderWidths.Right;
valBounds.Height -= borderWidths.Bottom;
int x = valBounds.X + (valBounds.Width - checkBoxSize.Width) / 2;
int y = valBounds.Y + (valBounds.Height - checkBoxSize.Height) / 2;
return new Rectangle(new Point(x, y), checkBoxSize);
}
protected virtual Size GetCheckBoxSize(Graphics g, CheckBoxState state) {
Size checkBoxSize;
if (Application.RenderWithVisualStyles) {
checkBoxSize = CheckBoxRenderer.GetGlyphSize(g, state);
switch (OwnerColumn.FlatStyle) {
case FlatStyle.Standard:
case FlatStyle.System:
break;
case FlatStyle.Flat:
checkBoxSize.Width -= 3;
checkBoxSize.Height -= 3;
break;
case FlatStyle.Popup:
checkBoxSize.Width -= 2;
checkBoxSize.Height -= 2;
break;
}
} else {
switch (OwnerColumn.FlatStyle) {
case FlatStyle.Flat:
checkBoxSize = CheckBoxRenderer.GetGlyphSize(g, state);
checkBoxSize.Width -= 3;
checkBoxSize.Height -= 3;
break;
case FlatStyle.Popup:
checkBoxSize = CheckBoxRenderer.GetGlyphSize(g, state);
checkBoxSize.Width -= 2;
checkBoxSize.Height -= 2;
break;
default: // FlatStyle.Standard || FlatStyle.System
checkBoxSize = new Size(SystemInformation.Border3DSize.Width * 2 + 9,
SystemInformation.Border3DSize.Width * 2 + 9);
break;
}
}
return checkBoxSize;
}
}
@blackholeearth
Copy link

blackholeearth commented May 28, 2024

hello.
how can i add "column name" near the checkbox . or below checkbox

edit: i have made the necessary changes

checbox headercell with text

checbox-headercell-with-text

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace eControls
{
    // https://gist.github.com/KOZ60/bf90763ff79e178c66844c8cd7c11a14

    public class DGVSelectAllCheckBoxHeaderCell : DataGridViewColumnHeaderCell
    {
        protected static class CheckBoxHeaderCellRenderer
        {
            private static readonly VisualStyleElement CheckBoxElement
                = VisualStyleElement.Button.CheckBox.UncheckedNormal;

            [ThreadStatic]
            static VisualStyleRenderer visualStyleRenderer;

            public static VisualStyleRenderer CheckBoxRenderer
            {
                get
                {
                    if (visualStyleRenderer == null)
                    {
                        visualStyleRenderer = new VisualStyleRenderer(CheckBoxElement);
                    }
                    return visualStyleRenderer;
                }
            }

            public static void DrawCheckBox(Graphics g, Rectangle bounds, CheckBoxState state  )
            {
                CheckBoxRenderer.SetParameters(CheckBoxElement.ClassName, CheckBoxElement.Part, (int)state);
                CheckBoxRenderer.DrawBackground(g, bounds, Rectangle.Truncate(g.ClipBounds));

                 
            }
        }

        private DataGridView _Owner;
        private CheckState? _AllCheckState = null;
        private int allCheckStateChangingCount = 0;
        private bool _MouseIsDown;
        private bool _MouseIsOver;

        public DGVSelectAllCheckBoxHeaderCell()
        {
            // For GetContentBounds
            Value = " ";
        }

        protected void Invalidate()
        {
            if (Owner != null && Owner.IsHandleCreated)
            {
                Owner.InvalidateCell(ColumnIndex, -1);
            }
        }

        protected override void OnDataGridViewChanged()
        {
            base.OnDataGridViewChanged();
            Owner = DataGridView;
        }

        protected DataGridView Owner
        {
            get
            {
                return _Owner;
            }
            set
            {
                if (_Owner != null)
                {
                    _Owner.CurrentCellDirtyStateChanged -= Owner_CurrentCellDirtyStateChanged;
                    _Owner.CellValueChanged -= Owner_CellValueChanged;
                    _Owner.RowsAdded -= Owner_RowsAdded;
                    _Owner.RowsRemoved -= Owner_RowsRemoved;
                    _Owner.DataError -= Owner_DataError;
                }
                _Owner = value;
                if (_Owner != null)
                {
                    _Owner.CurrentCellDirtyStateChanged += Owner_CurrentCellDirtyStateChanged;
                    _Owner.CellValueChanged += Owner_CellValueChanged;
                    _Owner.RowsAdded += Owner_RowsAdded;
                    _Owner.RowsRemoved += Owner_RowsRemoved;
                    _Owner.DataError += Owner_DataError;
                }
            }
        }

        protected DataGridViewCheckBoxColumn OwnerColumn
        {
            get
            {
                if (Owner != null)
                {
                    return Owner.Columns[ColumnIndex] as DataGridViewCheckBoxColumn;
                }
                return null;
            }
        }

        private void Owner_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            OnCurrentCellDirtyStateChanged(e);
        }

        private void Owner_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            OnCellValueChanged(e);
        }

        private void Owner_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
        {
            OnRowsRemoved(e);
        }

        private void Owner_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            OnRowsAdded(e);
        }

        private void Owner_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            OnDataError(e);
        }

        protected virtual void OnCurrentCellDirtyStateChanged(EventArgs e)
        {
            if (Owner.IsCurrentCellDirty &&
                Owner.CurrentCell.ColumnIndex == ColumnIndex)
            {
                Owner.CommitEdit(DataGridViewDataErrorContexts.Commit);
            }
        }

        protected virtual void OnCellValueChanged(DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == ColumnIndex && !AllCheckStateChanging)
            {
                ResetState();
            }
        }

        protected virtual void OnRowsRemoved(DataGridViewRowsRemovedEventArgs e)
        {
            ResetState();
        }

        protected virtual void OnRowsAdded(DataGridViewRowsAddedEventArgs e)
        {
            ResetState();
        }

        protected virtual void OnDataError(DataGridViewDataErrorEventArgs e)
        {
            if (e.ColumnIndex == ColumnIndex)
            {
                e.ThrowException = false;
            }
        }

        protected void ResetState()
        {
            _AllCheckState = null;
            Invalidate();
        }

        protected int CommittedRowCount
        {
            get
            {
                int rowCount = Owner.RowCount;
                if (rowCount > 0)
                {
                    if (Owner.Rows[rowCount - 1].IsNewRow)
                    {
                        return rowCount - 1;
                    }
                    else
                    {
                        return rowCount;
                    }
                }
                else
                {
                    return 0;
                }
            }
        }

        protected virtual CheckState AllCheckState
        {
            get
            {
                if (_AllCheckState.HasValue)
                {
                    return _AllCheckState.Value;
                }
                int checkedCount = 0;
                int rowCount = CommittedRowCount;
                if (rowCount > 0)
                {
                    for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
                    {
                        object value = Owner[ColumnIndex, rowIndex].FormattedValue;
                        if (value != null)
                        {
                            if (value is CheckState state)
                            {
                                switch (state)
                                {
                                    case CheckState.Checked:
                                        checkedCount++;
                                        break;
                                    case CheckState.Indeterminate:
                                        return CheckState.Indeterminate;
                                }
                            }
                            if (value is bool bChecked && bChecked)
                            {
                                checkedCount++;
                            }
                        }
                    }
                    if (checkedCount == 0)
                    {
                        _AllCheckState = CheckState.Unchecked;
                    }
                    else if (checkedCount == rowCount)
                    {
                        _AllCheckState = CheckState.Checked;
                    }
                    else
                    {
                        _AllCheckState = CheckState.Indeterminate;
                    }
                }
                else
                {
                    _AllCheckState = CheckState.Unchecked;
                }
                return _AllCheckState.Value;
            }
            set
            {
                if (AllCheckState != value)
                {
                    switch (value)
                    {
                        case CheckState.Checked:
                        case CheckState.Unchecked:
                            object setValue;
                            if (OwnerColumn.ThreeState)
                            {
                                if (value == CheckState.Checked)
                                {
                                    setValue = OwnerColumn.TrueValue ?? CheckState.Checked;
                                }
                                else
                                {
                                    setValue = OwnerColumn.FalseValue ?? CheckState.Unchecked;
                                }
                            }
                            else
                            {
                                if (value == CheckState.Checked)
                                {
                                    setValue = OwnerColumn.TrueValue ?? true;
                                }
                                else
                                {
                                    setValue = OwnerColumn.FalseValue ?? false;
                                }
                            }
                            AllCheckStateChanging = true;
                            try
                            {
                                int rowCount = CommittedRowCount;
                                if (Owner.IsCurrentCellInEditMode)
                                {
                                    Owner.EndEdit();
                                }
                                for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
                                {
                                    Owner[ColumnIndex, rowIndex].Value = setValue;
                                }
                            }
                            finally
                            {
                                AllCheckStateChanging = false;
                            }
                            break;
                    }
                    _AllCheckState = value;
                    Invalidate();
                }
            }
        }

        protected bool AllCheckStateChanging
        {
            get
            {
                return allCheckStateChangingCount > 0;
            }
            set
            {
                if (value)
                {
                    allCheckStateChangingCount++;
                }
                else
                {
                    if (allCheckStateChangingCount > 0)
                    {
                        allCheckStateChangingCount--;
                    }
                }
            }
        }

        protected virtual Rectangle ClickRectangle
        {
            get
            {
                using (var g = Owner.CreateGraphics())
                {
                    return GetContentBounds(g, OwnerColumn.InheritedStyle, -1);
                }
            }
        }

        protected bool MouseIsDown
        {
            get { return _MouseIsDown; }
            set
            {
                if (MouseIsDown != value)
                {
                    _MouseIsDown = value;
                    Invalidate();
                }
            }
        }

        protected bool MouseIsOver
        {
            get { return _MouseIsOver; }
            set
            {
                if (MouseIsOver != value)
                {
                    _MouseIsOver = value;
                    Invalidate();
                }
            }
        }

        protected override void OnMouseEnter(int rowIndex)
        {
            base.OnMouseEnter(rowIndex);
            var mouseLocation = Owner.PointToClient(Control.MousePosition);
            MouseIsOver = ClickRectangle.Contains(mouseLocation.X, mouseLocation.Y);
        }

        protected override void OnMouseLeave(int rowIndex)
        {
            base.OnMouseLeave(rowIndex);
            MouseIsOver = false;
            MouseIsDown = false;
        }

        protected override void OnMouseMove(DataGridViewCellMouseEventArgs e)
        {
            base.OnMouseMove(e);
            MouseIsOver = ClickRectangle.Contains(e.X, e.Y);
        }

        protected override void OnMouseDown(DataGridViewCellMouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (e.Button == MouseButtons.Left && ClickRectangle.Contains(e.X, e.Y))
            {
                MouseIsDown = true;
            }
        }

        protected override void OnMouseUp(DataGridViewCellMouseEventArgs e)
        {
            base.OnMouseUp(e);
            if (e.Button == MouseButtons.Left &&
                !OwnerColumn.ReadOnly &&
                ClickRectangle.Contains(e.X, e.Y) &&
                MouseIsDown)
            {
                if (CommittedRowCount > 0)
                {
                    if (AllCheckState == CheckState.Unchecked)
                    {
                        AllCheckState = CheckState.Checked;
                    }
                    else
                    {
                        AllCheckState = CheckState.Unchecked;
                    }
                }
                else
                {
                    AllCheckState = CheckState.Unchecked;
                }
            }
            MouseIsDown = false;
        }

        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, string.Empty, string.Empty, errorText, cellStyle, advancedBorderStyle, paintParts);
            Rectangle checkBoxBounds = 
                GetCheckBoxBounds(graphics, cellBounds,
                                  advancedBorderStyle, CheckBoxState.UncheckedNormal);
            CheckBoxState checkBoxState = GetCheckBoxState();
            DrawCheckBox(graphics, checkBoxBounds, checkBoxState);
        }

        protected virtual void DrawCheckBox(Graphics g, Rectangle checkBoxBounds, CheckBoxState checkBoxState)
        {
            if (Application.RenderWithVisualStyles)
            {
                CheckBoxHeaderCellRenderer.DrawCheckBox(g, checkBoxBounds, checkBoxState);

                //by me 2024
                string text = OwnerColumn.Name; //"hello";
                var font1 = Owner.ColumnHeadersDefaultCellStyle.Font; //ok
                var cellRectangle = Owner.GetCellDisplayRectangle(OwnerColumn.Index, -1, true);
                var color1 = Color.Black;
                ////put columnName , right below the checkBox Rect.
                //checkBoxBounds.Offset(-10, 13);
                //put columnName , right above the checkBox Rect.
                checkBoxBounds.Offset(-10, -13);
                cellRectangle.Y = checkBoxBounds.Y;

                ////CheckBoxRenderer.DrawText(g, bounds, text);
                //g.DrawString(text,
                //    font1, //Owner.Font,
                //    SystemBrushes.MenuText, 
                //    cellRectangle.Location,
                //    );

                // Create a TextFormatFlags with word wrapping, horizontal center and
                // vertical center specified.
                TextFormatFlags flags = TextFormatFlags.HorizontalCenter
                    ;
                    // | TextFormatFlags.VerticalCenter
                    //| TextFormatFlags.WordBreak;

                // Draw the text and the surrounding rectangle.
                TextRenderer.DrawText(g, text, font1, cellRectangle, color1, flags); //Color.Blue ,darkblue


            }
            else
            {
                ButtonState bs = ToButtonState(checkBoxState);
                if (IsMixDraw(checkBoxState))
                {
                    ControlPaint.DrawMixedCheckBox(g, checkBoxBounds, bs);
                }
                else
                {
                    ControlPaint.DrawCheckBox(g, checkBoxBounds, bs);
                }
            }
        }

        protected virtual ButtonState ToButtonState(CheckBoxState checkBoxState)
        {
            ButtonState bs;
            switch (checkBoxState)
            {
                case CheckBoxState.UncheckedNormal:
                case CheckBoxState.UncheckedHot:
                case CheckBoxState.UncheckedPressed:
                case CheckBoxState.UncheckedDisabled:
                    bs = ButtonState.Normal;
                    break;
                case CheckBoxState.CheckedNormal:
                case CheckBoxState.CheckedHot:
                case CheckBoxState.CheckedPressed:
                case CheckBoxState.CheckedDisabled:
                    bs = ButtonState.Checked;
                    break;
                default:
                    bs = ButtonState.Inactive;
                    break;
            }
            switch (checkBoxState)
            {
                case CheckBoxState.UncheckedPressed:
                case CheckBoxState.CheckedPressed:
                case CheckBoxState.MixedPressed:
                    bs |= ButtonState.Pushed;
                    break;
            }
            return bs;
        }

        protected virtual bool IsMixDraw(CheckBoxState checkBoxState)
        {
            switch (checkBoxState)
            {
                case CheckBoxState.MixedNormal:
                case CheckBoxState.MixedHot:
                case CheckBoxState.MixedPressed:
                case CheckBoxState.MixedDisabled:
                    return true;
            }
            return false;
        }

        protected virtual CheckBoxState GetCheckBoxState()
        {
            if (OwnerColumn.ReadOnly)
            {
                return CheckBoxState.MixedDisabled;
            }
            else
            {
                if (MouseIsDown)
                {
                    return CheckBoxState.UncheckedPressed;
                }
                else
                {
                    switch (AllCheckState)
                    {
                        case CheckState.Checked:
                            return CheckBoxState.CheckedNormal;
                        case CheckState.Unchecked:
                            return CheckBoxState.UncheckedNormal;
                        default:
                            return CheckBoxState.MixedNormal;
                    }
                }
            }
        }

       
        protected virtual Rectangle GetCheckBoxBounds(Graphics g, Rectangle cellBounds,
                                            DataGridViewAdvancedBorderStyle advancedBorderStyle,
                                            CheckBoxState state)
        {
            var font1 = Owner.ColumnHeadersDefaultCellStyle.Font; //ok
            int textHeight = font1.Height; //1 line height


            Size checkBoxSize = GetCheckBoxSize(g, state);
            Rectangle valBounds = cellBounds;
            valBounds.Width -= 1;
            Rectangle borderWidths = BorderWidths(advancedBorderStyle);
            valBounds.Offset(borderWidths.X, borderWidths.Y);
            valBounds.Width -= borderWidths.Right;
            valBounds.Height -= borderWidths.Bottom;
            int x = valBounds.X + (valBounds.Width - checkBoxSize.Width) / 2;
            int y = valBounds.Y + (valBounds.Height - checkBoxSize.Height + textHeight) / 2;
            return new Rectangle(new Point(x, y), checkBoxSize);
        }

        protected virtual Rectangle GetCheckBoxBounds_ORG_center(Graphics g, Rectangle cellBounds,
                                         DataGridViewAdvancedBorderStyle advancedBorderStyle,
                                         CheckBoxState state)
        {
            Size checkBoxSize = GetCheckBoxSize(g, state);
            Rectangle valBounds = cellBounds;
            valBounds.Width -= 1;
            Rectangle borderWidths = BorderWidths(advancedBorderStyle);
            valBounds.Offset(borderWidths.X, borderWidths.Y);
            valBounds.Width -= borderWidths.Right;
            valBounds.Height -= borderWidths.Bottom;
            int x = valBounds.X + (valBounds.Width - checkBoxSize.Width) / 2;
            int y = valBounds.Y + (valBounds.Height - checkBoxSize.Height) / 2;
            return new Rectangle(new Point(x, y), checkBoxSize);
        }


        protected virtual Size GetCheckBoxSize(Graphics g, CheckBoxState state)
        {
            Size checkBoxSize;
            if (Application.RenderWithVisualStyles)
            {
                checkBoxSize = CheckBoxRenderer.GetGlyphSize(g, state);
                switch (OwnerColumn.FlatStyle)
                {
                    case FlatStyle.Standard:
                    case FlatStyle.System:
                        break;
                    case FlatStyle.Flat:
                        checkBoxSize.Width -= 3;
                        checkBoxSize.Height -= 3;
                        break;
                    case FlatStyle.Popup:
                        checkBoxSize.Width -= 2;
                        checkBoxSize.Height -= 2;
                        break;
                }
            }
            else
            {
                switch (OwnerColumn.FlatStyle)
                {
                    case FlatStyle.Flat:
                        checkBoxSize = CheckBoxRenderer.GetGlyphSize(g, state);
                        checkBoxSize.Width -= 3;
                        checkBoxSize.Height -= 3;
                        break;
                    case FlatStyle.Popup:
                        checkBoxSize = CheckBoxRenderer.GetGlyphSize(g, state);
                        checkBoxSize.Width -= 2;
                        checkBoxSize.Height -= 2;
                        break;
                    default: // FlatStyle.Standard || FlatStyle.System
                        checkBoxSize = new Size(SystemInformation.Border3DSize.Width * 2 + 9,
                            SystemInformation.Border3DSize.Width * 2 + 9);
                        break;
                }
            }
            return checkBoxSize;
        }
  
    
    }




}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment