DataGridView row: Semi-transparent selection or row border on selection

北战南征 提交于 2019-12-04 19:23:00


I have a DataGridView where the background of each row is different depending on the data bound item. Though, when I select a row, I can no longer see its original background color.

To solve this, I have thought of two solutions:

I can make the selections semi-transparent, making it possible to see if two selected rows have different background colors.

Or; I can remove the selection colors entirely, and draw a border around the selected rows.

What option is easier and how can I do this?

It's a WinForm app.

Edit: I ended up using some of your code, adrift

    private void dgv_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
        if (dgv.Rows[e.RowIndex].Selected)
            var row = dgv.Rows[e.RowIndex];
            var bgColor = row.DefaultCellStyle.BackColor;
            row.DefaultCellStyle.SelectionBackColor = Color.FromArgb(bgColor.R * 5 / 6, bgColor.G * 5 / 6, bgColor.B * 5 / 6);

This gives the impression of a semi-transparent selection color. Thanks for your help!


If you want to draw a border around selected rows, you can use the DataGridView.RowPostPaintEvent, and to 'clear' the selection colors, you can use the DataGridViewCellStyle.SelectionBackColor and DataGridViewCellStyle.SelectionForeColor properties.

For example, if I set the row cell style like this

row.DefaultCellStyle.BackColor = Color.LightBlue;
row.DefaultCellStyle.SelectionBackColor = Color.LightBlue;
row.DefaultCellStyle.SelectionForeColor = dataGridView1.ForeColor;

I can add this code to the RowPostPaintEvent

private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
    if (dataGridView1.Rows[e.RowIndex].Selected)
        using (Pen pen = new Pen(Color.Red))
            int penWidth = 2;

            pen.Width = penWidth;

            int x = e.RowBounds.Left + (penWidth / 2);
            int y = e.RowBounds.Top + (penWidth / 2);
            int width = e.RowBounds.Width - penWidth;
            int height = e.RowBounds.Height - penWidth;

            e.Graphics.DrawRectangle(pen, x, y, width, height);

and a selected row will display like this:

row with border