You probably want to override the RowPrePaint event. There is sample code at
DataGridView..::.RowPrePaint Event[
^] on how to paint a gradient row background if the row is selected. You would just need to modify it to your needs.
[Update]
Man, it took me forever to actually figure out how to implement that. All I had to do was set the RowTemplate's DefaultCellStyle's BackColor to Transparent to make it work, but it took me a while to figure that out.
Anyway, I'm not sure what you mean by it's not painting correctly. Whenever you resize the DataGridView, it repaints. I verified this by simply having the form resize the DGV if I resized the form, and I had the RowPrePaint print "RowPrePaint" to the debugger window.
I do see some problems with your code, though. Primarily that when you create a New Rectangle, you want to pass in the top, left location, and the height and width. You instead pass in the top, left and bottom, right. With your code, it was painting below the rows available.
Change it to:
Dim P1 As New System.Drawing.Point(New System.Drawing.Point(Left, Top))
Dim P2 As New System.Drawing.Point(New System.Drawing.Point(Right - Left, Bottom - Top))
The other problem I see is that e.RowBounds.Right extends beyond the columns if the DGV is wider than the columns are. You can fix that using the GetColumnDisplayRectangle. Change to:
Dim Top As Integer = e.RowBounds.Top
Dim Bottom As Integer = e.RowBounds.Bottom
Dim lastColumnRect As Rectangle = _
DataGridView1.GetColumnDisplayRectangle(DataGridView1.ColumnCount - 1, False)
Dim Right As Integer = lastColumnPt.X + lastColumnPt.Width
Dim Left As Integer = e.RowBounds.Left
With those changes, it will only draw within the actual row bounds.
It's also interesting to note that when you move any of the scrollbars, it also repaints. So you could go iteratively through the columns using the GetColumnDisplayRectangle and set the last input to true to only get the columns that are actually in the display and you could set the rectangle to that.