Home > Enterprise >  Custom DataGridViewCell repainting
Custom DataGridViewCell repainting

Time:10-17

I am trying to create a custom DataGridViewColumn to create a modern looking checkbox style column using images.

This is my code so far:

   public class CustomDataGridColumn : DataGridViewColumn
    {
        public CustomDataGridColumn()
        {
            this.CellTemplate = new CustomDataGridCell();
        }
    }

    public class CustomDataGridCell : DataGridViewCell
    {
        private static Image img = Resources.UncheckedBox;
        public bool Checked { get; set; }

        public CustomDataGridCell()
        {
            Checked = false;
        }
        protected override object GetFormattedValue(object value,
            int rowIndex, ref DataGridViewCellStyle cellStyle,
            TypeConverter valueTypeConverter,
            TypeConverter formattedValueTypeConverter,
            DataGridViewDataErrorContexts context)
        {
            return img;
        }

        protected override void OnClick(DataGridViewCellEventArgs e)
        {
            if (Checked)
            {
                Checked = false;
                //Change the image to Resource.UncheckedBox;
            }
            else
            {
                Checked = true;
                //Change the image to Resource.CheckedBox;
            }
            base.OnClick(e);
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
            DataGridViewElementStates cellState, object value, object formattedValue, string errorText,
            DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle,
            DataGridViewPaintParts paintParts)
        {
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value,
                formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);

            graphics.DrawImage(Resources.CheckedBox, new Point(cellBounds.Width/2, cellBounds.Y));
        }
    }

There are two PNG images that represent the state of the checkbox (i.e. checked or unchecked). These are stored as Resources and have are accessible by Resources.CheckedBox and Resources.UncheckedBox. I only want the image to be in the column, there is no text required. The text in the bugged UI in the example below comes from other columns that are in Data Grid

I have two questions:

  1. When I change the width of the columns by clicking and dragging, the cells do not re-draw properly and the UI becomes bugged. How do I fix this?

  2. When the user clicks the cell, I want the image to change to the correct image depending on the state. How can I do this?

Example screenshot of the bugged UI:

enter image description here

CodePudding user response:

Derive from SO74087396A

Run...

SO74087396B

You might need here to enable the grid's DoubleBuffered feature to get rid of the flicker or at least to reduce it. Either derive a new class from DataGridView and set DoubleBuffered = true; in the constructor, or use Reflection to enable this property if you don't want to create a new type.

In the grid's Form ctor:

//  
using System.Reflection;
// ...

public SomeFormConstructor()
{
    InitializeComponent();

    yourDGV.GetType()
        .GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic)
        .SetValue(yourDGV, true);
}

Related

Change CheckBox size of DataGridViewCheckBoxCell and increase the clickable area

  •  Tags:  
  • c#
  • Related