Строка DataGridView: полупрозрачный выбор или граница строки при выборе

У меня есть DataGridView, где фон каждой строки отличается в зависимости от связанного с данными элемента. Хотя, когда я выбираю строку, я больше не могу видеть ее исходный цвет фона.

Чтобы решить эту проблему, я подумал о двух решениях:

Я могу сделать выбор полупрозрачным, позволяя увидеть, имеют ли два выделенных ряда разные цвета фона.

Или; Я могу полностью удалить цвета выделения и нарисовать границу вокруг выбранных строк.

Какой вариант проще и как я могу это сделать?

Это приложение WinForm.

Редактирование: в итоге я использовал часть вашего кода, 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);
        }
    }

Это создает впечатление полупрозрачного цвета выбора. Спасибо за вашу помощь!

Ответ 1

Если вы хотите нарисовать границу вокруг выбранных строк, вы можете использовать DataGridView.RowPostPaintEvent и "очистить" цвета выбора, вы можете использовать DataGridViewCellStyle.SelectionBackColor и DataGridViewCellStyle.SelectionForeColor свойства.

Например, если я установил стиль ячейки строки, как этот

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

Я могу добавить этот код в 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);
        }
    }
}

и выбранная строка будет выглядеть следующим образом:

row with border