Mike
Mike

Reputation: 1312

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

Upvotes: 4

Views: 14609

Answers (1)

OhBeWise
OhBeWise

Reputation: 5454

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

Upvotes: 13

Related Questions