Change Color of Button in DataGridView Cell
Asked Answered
W

8

16

I have a large DataGridView control that has several cells most of which contain a button. How can I change the color of those buttons?

This changes the "outline" of the button but not the button itself.

row.Cells[2].Style.BackColor = System.Drawing.Color.Red;

This doesn't seem to change anything that's visible:

row.Cells[2].Style.ForeColor = System.Drawing.Color.Red;

If it's not possible to change the background, is it possible to change the font on the button?

Using .NET 2.0.

Whyte answered 25/2, 2009 at 16:51 Comment(1)
F
13

As per MSDN:

When visual styles are enabled, the buttons in a button column are painted using a ButtonRenderer, and cell styles specified through properties such as DefaultCellStyle have no effect.

Therefore, you have one of two choices. In your Program.cs you can remove this line:

Application.EnableVisualStyles();

which will make it work, but make everything else look like crap. Your other option, and you're not going to like this one, is to inherit from DataGridViewButtonCell and override the Paint() method. You can then use the static method on the ButtonRenderer class called DrawButton, to paint the button yourself. That means figuring out which state the cell currently is in (clicked, hover etc.) and painting the corners and borders etc... You get the idea, it's doable, but a HUGE pain.

If you want to though, here's just some sample code to get you started:

 //Custom ButtonCell
 public class MyButtonCell : DataGridViewButtonCell
    {
        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            ButtonRenderer.DrawButton(graphics, cellBounds, formattedValue.ToString(), new Font("Comic Sans MS", 9.0f, FontStyle.Bold), true, System.Windows.Forms.VisualStyles.PushButtonState.Default);
        }
    }

Then here's a test DataGridView:

DataGridViewButtonColumn c = new DataGridViewButtonColumn();
            c.CellTemplate = new MyButtonColumn();
            this.dataGridView1.Columns.Add(c);
            this.dataGridView1.Rows.Add("Click Me");

All this sample does, is paint a button with the font being "Comic Sans MS". It doesn't take into account the state of the button as you'll see when you run the app.

GOOD LUCK!!

Friesian answered 25/2, 2009 at 19:6 Comment(1)
In my case, I had to render other then the button itself parts of cells too, i.e. grid lines etc. As a quick-n-dirty fix you may call base.Paint(...), the DEFLATE cellBounds by a couple of pixel (to make sure that area around the button will stay), and then call ButtonRenderer.DrawButtonNoshow
J
33

I missed Dave's note on Tomas' answer so i am just posting the simple solution to this.

Update the FlatStyle property of the Button column to Popup and then by updating the backcolor and forecolor you can change the appearance of the button.

DataGridViewButtonColumn c = (DataGridViewButtonColumn)myGrid.Columns["colFollowUp"];
c.FlatStyle = FlatStyle.Popup;
c.DefaultCellStyle.ForeColor = Color.Navy;
c.DefaultCellStyle.BackColor = Color.Yellow;
Javelin answered 7/5, 2010 at 21:38 Comment(0)
F
13

As per MSDN:

When visual styles are enabled, the buttons in a button column are painted using a ButtonRenderer, and cell styles specified through properties such as DefaultCellStyle have no effect.

Therefore, you have one of two choices. In your Program.cs you can remove this line:

Application.EnableVisualStyles();

which will make it work, but make everything else look like crap. Your other option, and you're not going to like this one, is to inherit from DataGridViewButtonCell and override the Paint() method. You can then use the static method on the ButtonRenderer class called DrawButton, to paint the button yourself. That means figuring out which state the cell currently is in (clicked, hover etc.) and painting the corners and borders etc... You get the idea, it's doable, but a HUGE pain.

If you want to though, here's just some sample code to get you started:

 //Custom ButtonCell
 public class MyButtonCell : DataGridViewButtonCell
    {
        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            ButtonRenderer.DrawButton(graphics, cellBounds, formattedValue.ToString(), new Font("Comic Sans MS", 9.0f, FontStyle.Bold), true, System.Windows.Forms.VisualStyles.PushButtonState.Default);
        }
    }

Then here's a test DataGridView:

DataGridViewButtonColumn c = new DataGridViewButtonColumn();
            c.CellTemplate = new MyButtonColumn();
            this.dataGridView1.Columns.Add(c);
            this.dataGridView1.Rows.Add("Click Me");

All this sample does, is paint a button with the font being "Comic Sans MS". It doesn't take into account the state of the button as you'll see when you run the app.

GOOD LUCK!!

Friesian answered 25/2, 2009 at 19:6 Comment(1)
In my case, I had to render other then the button itself parts of cells too, i.e. grid lines etc. As a quick-n-dirty fix you may call base.Paint(...), the DEFLATE cellBounds by a couple of pixel (to make sure that area around the button will stay), and then call ButtonRenderer.DrawButtonNoshow
B
4

The default button in a DataGridView is drawn using the ButtonRenderer which makes it quite difficult to override. if I were you, I'd just set the button FlatStyle to "Popup".

var buttonCell = (DataGridViewButtonCell)dataGridMappings.Rows[0].Cells[0];
buttonCell.FlatStyle = FlatStyle.Popup;
buttonCell.Style.BackColor = System.Drawing.Color.Red;
Bouffant answered 2/8, 2013 at 18:24 Comment(1)
Many thanks for this quick and efficient solution!Diastyle
A
1

If these cells contain a button I am quite sure you have to access that button's property BackColor. Ie. get the value of the cell convert it to a button and set it's property.

Amidase answered 25/2, 2009 at 17:19 Comment(1)
Yes, the BackColor property is there and it changes the outline of the button not the button itself. I actually had to change the FlatStyle of the button to "Popup" or "Flat" to get it to work.Whyte
D
1

I had the same problem.

All you have to do is to

  1. Set the following property of the DataGridView's ButtonColumn:

    FlatStyle = PopUp

  2. Set the cell's color:

    row.Cells[2].Style.BackColor = System.Drawing.Color.Red;

Drudge answered 21/7, 2020 at 10:16 Comment(0)
G
0

I think you're accessing it wrong:

row.Cells[2].Style.BackColor = System.Drawing.Color.Red;

you say updates the "outline" of the button, but it's really updating the cell behind the button.

something like this should work:

row.Cells[2].ButtonName.Style.BackColor = System.Drawing.Color.Red;
Graphite answered 25/2, 2009 at 18:26 Comment(0)
U
0

It's absolutely enough to make your own class derived from DataGridViewButtonCell with a custom Paint method, without removing EnableVisualStyles().

Unravel answered 25/4, 2011 at 5:25 Comment(0)
P
0

Change cell FlatStyle to the following:

var buttonCell = (DataGridViewButtonCell)dataGridMappings.Rows[0].Cells[0];
buttonCell.FlatStyle = FlatStyle.Flat;
buttonCell.Style.BackColor = System.Drawing.Color.Red;

It will work.

Parsnip answered 21/5, 2019 at 0:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.