Question

I have a custom ComboBox control that I want to use in a DataGridViewCell. I first inherited DataGridViewCell and am trying to override the Paint() method to paint the ComboBox in the cell.

My problem is that after inheriting DataGridViewColumn and setting the CellTemplate property to a new instance of my CustomDataGridViewCell class, the cell is grey with no contents.

The cBox class variable is instantiated in the object ctor.

protected override void Paint(Graphics graphics, Rectangle clipBounds, 
   Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, 
   object value, object formattedValue, string errorText, 
   DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle borderStyle,
   DataGridViewPaintParts paintParts)
{
   // Call MyBase.Paint() without passing object for formattedValue param
   base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, 
       "", errorText, cellStyle, borderStyle, paintParts);
    
   // Set ComboBox properties
   this.cBox.CheckOnClick = true;
   this.cBox.DrawMode = System.Windows.Forms.DrawMode.Normal;
   this.cBox.DropDownHeight = 1;
   this.cBox.IntegralHeight = false;
   this.cBox.Location = new System.Drawing.Point(cellBounds.X, cellBounds.Y);
   this.cBox.Size = new System.Drawing.Size(cellBounds.Width, cellBounds.Height);
   this.cBox.ValueSeparator = ", ";
   this.cBox.Visible = true;
   this.cBox.Show();
}

How can I correctly paint the ComboBox in the cell?

Was it helpful?

Solution

I made fairly simple change that fixes my problem.

I had to correct the coordinates to be relative to the window instead of the DataGridView, call Controls.Add() for the owning form, and reposition the control in front of the DataGridView:

protected override void Paint(Graphics graphics, Rectangle clipBounds, 
   Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, 
   object value, object formattedValue, string errorText, 
   DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle borderStyle, 
   DataGridViewPaintParts paintParts)
{
   // Just paint the border (because it shows outside the ComboBox bounds)
   this.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, borderStyle);

   int cellX = this.DataGridView.Location.X + cellBounds.X;
   int cellY = this.DataGridView.Location.Y + cellBounds.Y;

   // Create ComboBox and set properties
   this.cBox = new CheckedComboBox();
   this.cBox.DropDownHeight = 1;
   this.cBox.IntegralHeight = false;
   this.cBox.Location = new Point(cellX, cellY);
   this.cBox.Size = new Size(cellBounds.Width, cellBounds.Height);
   this.cBox.ValueSeparator = ", ";
    
   // Add to form and position in front of DataGridView
   this.DataGridView.FindForm.Controls.Add(this.cBox);
   this.cBox.BringToFront();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top