问题
If a certain condition is met I want to change the outline of the DataGridViewRow
to blue to have it stand out. I know it isn't the BackColor
since it changes the row's background color. I have tried to change the ForeColor
to Blue but nothing changes. I wouldn't believe it is the selection styles since that behavior isn't what I am looking for. Any suggestions to get this behavior?
item
below is a DataGridViewRow.
item.DefaultCellStyle.ForeColor = Color.Blue
item.DefaultCellStyle.BackColor = Color.Blue
Thanks to help from Jimi.
I added to my datagridview.Paint
Dim visibleColumsWidth As Integer = dataGridView.Columns.GetColumnsWidth(DataGridViewElementStates.Visible)
Dim y As Integer = dataGridView.GetCellDisplayRectangle(Column.DisplayIndex, rowIndex, True).Top
Dim rect As New Rectangle(dataGridView.RowHeadersWidth, y, visibleColumsWidth, item.Height - 1)
e.Graphics.DrawRectangle(Pens.Blue, rect)
回答1:
You can handle the RowPostPaint or RowPrePaint events to to paint the border of one or more Rows, based on specific conditions.
Here, I'm using the RowPostPaint
event handler, since you may have already some painting procedure in your DataGridView: RowPostPaint
allows to paint over an already drawn Row, redefining some details. There's no e.Handled
property to set, since the drawing has already been performed at this point.
The Handled
property is used to specify whether the event handler has completely handled the event or whether the system should complete the process.
- As usual, the bounding rectangle need to be adjusted, because of the way GDI+ draws this shape.
- You probably don't want to outline the row Header, which is included in the
e.RowBounds
value, so we need to subtract the DataGridView.RowHeadersWidth from thee.RowBounds.Width
. - The outline should be applied only to the visible Columns, so we can use the DataGridView.Columns.GetColumnsWidth() method to get this measure, specifying
DataGridViewElementStates.Visible
as the Column state.
► Replace [Some Condition]
with the condition that should generate the outlining in your context.
Private Sub dataGridView1_RowPostPaint(sender As Object, e As DataGridViewRowPostPaintEventArgs) Handles DataGridView1.RowPostPaint
If [Some Condition] Then
Dim visibleColumsWidth As Integer = dataGridView1.Columns.GetColumnsWidth(DataGridViewElementStates.Visible)
Dim rect = New Rectangle(dataGridView1.RowHeadersWidth, e.RowBounds.Top - 1, visibleColumsWidth, e.RowBounds.Height)
e.Graphics.DrawRectangle(Pens.Blue, rect)
End If
End Sub
If you instead want to outline a single cell, then handle the CellPainting event:
Here, we paint all parts but override the Cell border default drawing, using the e.Graphics.DrawRectangle()
method. The Cell bounding rectangle measure is slightly different, adapted to how the cell's internal borders are painted, so the new border overlaps the default one.
We also set e.Handled = True
, to notify that the drawing has been handled and there's no need to do anything else.
Private Sub dataGridView1_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
If e.RowIndex < 0 OrElse e.ColumnIndex < 0 Then Return
If [Some Condition] Then
Dim rect = New Rectangle(e.CellBounds.X - 1, e.CellBounds.Y - 1, e.CellBounds.Width, e.CellBounds.Height)
e.PaintBackground(e.CellBounds, True)
e.PaintContent(e.CellBounds)
e.Graphics.DrawRectangle(Pens.Red, rect)
e.Handled = True
End If
End Sub
This is the rendering with the current values:
If you prefer to draw the border inside the Cells' bounds (or use a thicker Pen), move Left/Top down 1 pixel and shorten the height by 1 pixel.
来源:https://stackoverflow.com/questions/61104992/changing-the-outline-of-a-datagridviewrow