Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change the back color of the cell for DataGridViewComboBoxColumn

I created a DataGridView object with columns of type DataGridViewComboBoxColumn to allow the user to select values from a drop down list. I want to color the back of the combo box if the user selected "high" for example. However, it doesn't color the combo box but only the combo box values.

The code is:

dgvOverallRisk.Rows[0].Cells[1].Style.ForeColor = Color.Aqua;
dgvOverallRisk.Rows[0].Cells[1].Style.BackColor = Color.Red;

And it looks like this:

enter image description here

enter image description here

like image 782
Mike Avatar asked Feb 10 '23 08:02

Mike


1 Answers

Coincidentally, I just answered a similar question on the ForeColor found here. Essentially the same, you have two options:

  1. Set the FlatStyle. It might not look the way you want though.

    theComboBoxColumn.FlatStyle = FlatStyle.Flat;
    
  2. This is not an exact solution for you, as I am on Windows 8.1 and judging by your screenshots, you're on Windows 7. They have differing display styles on their ComboBox controls, but this should give you a general idea of a possible direction you could take. Handle the DataGridView.CellPainting and DataGridView.EditingControlShowing events to manually draw the ComboBox cells.

    this.dataGridView1.CellPainting += this.dataGridView1_CellPainting;
    this.dataGridView1.EditingControlShowing += this.dataGridView1_EditingControlShowing;
    
    this.dataGridView1.Rows[0].Cells[1].Style.ForeColor = Color.DarkRed;
    this.dataGridView1.Rows[0].Cells[1].Style.BackColor = Color.Bisque;
    this.dataGridView1.Rows[1].Cells[1].Style.ForeColor = Color.SpringGreen;
    this.dataGridView1.Rows[1].Cells[1].Style.BackColor = Color.Purple;
    
    // Paint the cell when not in edit mode.
    private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
    {
      if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
      {
        if (this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] is DataGridViewComboBoxCell)
        {
          var cell = this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewComboBoxCell;
          var foreColor = cell.Style.ForeColor.Name == "0" ? Color.Black : cell.Style.ForeColor;

          e.Paint(e.ClipBounds, DataGridViewPaintParts.Border);
          e.Paint(e.ClipBounds, DataGridViewPaintParts.ContentBackground);

          using (Brush forebrush = new SolidBrush(foreColor))
          using (Brush backbrush = new SolidBrush(cell.Style.BackColor))
          using (StringFormat format = new StringFormat())
          {
            Rectangle rect = new Rectangle(e.CellBounds.X + 1, e.CellBounds.Y + 1, e.CellBounds.Width - 19, e.CellBounds.Height - 3);
            format.LineAlignment = StringAlignment.Center;

            e.Graphics.FillRectangle(backbrush, rect);
            e.Graphics.DrawString(cell.FormattedValue.ToString(), e.CellStyle.Font, forebrush, rect, format); 
          }

          e.Paint(e.ClipBounds, DataGridViewPaintParts.ErrorIcon);
          e.Paint(e.ClipBounds, DataGridViewPaintParts.Focus);
          e.Handled = true;
        }
      }
    }

    // Paint the cell in edit mode.
    private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {
      if (this.dataGridView1.CurrentCellAddress.X == combo.DisplayIndex)
      {
        ComboBox cb = e.Control as ComboBox;
        if (cb != null)
        {
          cb.DropDownStyle = ComboBoxStyle.DropDownList;

          cb.DrawMode = DrawMode.OwnerDrawFixed;
          cb.DrawItem -= this.cb_DrawItem;
          cb.DrawItem += this.cb_DrawItem;
        }
      }
    }

    // Manually paint the combobox.
    private void cb_DrawItem(object sender, DrawItemEventArgs e)
    {
      ComboBox cb = sender as ComboBox;

      // Non-sourced vs sourced examples.
      string value = cb.Items[e.Index].ToString();
      // string value = (cb.DataSource as DataTable).Rows[e.Index].ItemArray[SourceColumnIndex];

      if (e.Index >= 0)
      {
        using (Brush forebrush = new SolidBrush(cb.ForeColor))
        using (Brush backbrush = new SolidBrush(cb.BackColor))
        {
          e.Graphics.FillRectangle(backbrush, e.Bounds);
          e.DrawBackground();
          e.DrawFocusRectangle();
          e.Graphics.DrawString(value, e.Font, forebrush, e.Bounds);
        }
      }
    }

Back/Fore-ground colored DataGridViewComboBoxCell examples

like image 141
OhBeWise Avatar answered Feb 12 '23 11:02

OhBeWise