滚动完成后刷新画图

Refresh Paint after Scroll is Completed

我有一个数据网格视图,它在选定的单元格周围放置了一个黑色边框。我的代码工作正常,直到我在进行选择时滚动。当我在进行选择时向下滚动时我的顶部边框消失了,这在这一点上不是问题,因为它表明有更多选定的单元格不在视图中,我遇到的问题是一旦我做出选择然后 return 到顶部,顶部边框永远不会 returns。我注意到在进入单元格时,dgv 会重新绘制,我认为这就是我的顶部边框未绘制的原因,因为它不在视野范围内,一旦我滚动回顶部,我就不会进入任何新单元格,因此顶部边框永远不会重新绘制。

所以我添加了一个滚动事件来刷新我的 dgv 绘制,但这似乎是重绘然后滚动而不是滚动重绘,这导致进一步选定的单元格边框不显示。

所以我的问题是,有没有办法在滚动完成后触发重绘?

下面是我的代码,不确定是否与显示相关,但在这里。

    Private Sub dgvdefault_paint(sender As Object, e As PaintEventArgs)
    With dgvdefault

        ' draw border around dgv
        e.Graphics.DrawRectangle(penborder, 0, 0, .Width - 1, .Height - 1)


        For Each cell In .SelectedCells

            ' get cell position and size

            a = cell.rowindex
            b = cell.columnindex

            Dim myrect As Rectangle = (.GetCellDisplayRectangle(b, a, False))
            Dim dgvdefault_headerrectangle As Rectangle = (.GetCellDisplayRectangle(-1, -1, False))

            ' top border

            If a = 0 Then
                e.Graphics.DrawLine(Pens.Black, myrect.X - 1, myrect.Y - 1, myrect.X - 1 + myrect.Width, myrect.Y - 1)
            ElseIf .Rows(a - 1).Cells(b).Selected = False Then
                e.Graphics.DrawLine(Pens.Black, myrect.X - 1, myrect.Y - 1, myrect.X - 1 + myrect.Width, myrect.Y - 1)
            End If

            ' bottom border

            If a = .RowCount - 1 Then
                e.Graphics.DrawLine(Pens.Black, myrect.X - 1, myrect.Y - 1 + myrect.Height, myrect.X - 1 + myrect.Width, myrect.Y - 1 + myrect.Height)
            ElseIf .Rows(a + 1).Cells(b).Selected = False Then
                e.Graphics.DrawLine(Pens.Black, myrect.X - 1, myrect.Y - 1 + myrect.Height, myrect.X - 1 + myrect.Width, myrect.Y - 1 + myrect.Height)
            End If

            ' left border

            If b = 0 Then
                e.Graphics.DrawLine(Pens.Black, myrect.X - 1, myrect.Y - 1, myrect.X - 1, myrect.Y - 1 + myrect.Height)
            ElseIf .Rows(a).Cells(b - 1).Selected = False Then
                e.Graphics.DrawLine(Pens.Black, myrect.X - 1, myrect.Y - 1, myrect.X - 1, myrect.Y - 1 + myrect.Height)
            End If

            ' right border

            If b = .ColumnCount - 1 Then
                e.Graphics.DrawLine(Pens.Black, myrect.X - 1 + myrect.Width, myrect.Y - 1, myrect.X - 1 + myrect.Width, myrect.Y - 1 + myrect.Height)
            ElseIf .Rows(a).Cells(b + 1).Selected = False Then
                e.Graphics.DrawLine(Pens.Black, myrect.X - 1 + myrect.Width, myrect.Y - 1, myrect.X - 1 + myrect.Width, myrect.Y - 1 + myrect.Height)
            End If

        Next

    End With

End Sub

Private Sub dgvdefault_scroll(sender As Object, e As ScrollEventArgs)

    dgvdefault.Refresh()

End Sub

ScrollEventArgs 有一个类型枚举,您可以在条件分支中对其求值。

编辑* datagridview 不会显示所有滚动事件类型,因此我们使用反射为内部组件事件添加侦听器。

示例:

Option Strict On
Option Explicit On
Option Infer Off
Imports System.Reflection
Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        DataGridView1.ColumnCount = 10
        For i As Integer = 0 To 100
            Dim row As New DataGridViewRow
            DataGridView1.Rows.Add(row)
        Next
        DGVAddListener(DataGridView1)
    End Sub
    Public Function DGVAddListener(dataGridView As DataGridView) As Boolean
        Dim pInfo As PropertyInfo = dataGridView.GetType.GetProperty("VerticalScrollBar", BindingFlags.Instance Or BindingFlags.NonPublic)
        If pInfo Is Nothing Then Return False
        Dim dgvScrollBar As ScrollBar = CType(pInfo.GetValue(dataGridView, Nothing), ScrollBar)
        If dgvScrollBar is Nothing then Return False 
        AddHandler dgvScrollBar.Scroll, New ScrollEventHandler(AddressOf dgv_Scroll)
        Return True
    End Function
    Public Sub dgv_Scroll(sender As Object, e As ScrollEventArgs)
        Select Case e.Type
            Case ScrollEventType.EndScroll
                MsgBox("Scroll End!")
            Case ScrollEventType.First
            Case ScrollEventType.LargeDecrement
            Case ScrollEventType.LargeIncrement
            Case ScrollEventType.Last
            Case ScrollEventType.SmallDecrement
            Case ScrollEventType.SmallIncrement
            Case ScrollEventType.ThumbPosition
            Case ScrollEventType.ThumbTrack
        End Select
    End Sub
End Class

这不是最好的答案,但这是我想出的让我的 dgv 刷新 post 滚动的方法,这似乎效果很好(延迟很少)。

Private Sub dgvdefault_scroll(sender As Object, e As ScrollEventArgs)
    AddHandler timer1.Tick, AddressOf timer1_tick
End Sub
Private Sub timer1_tick(sender As Object, e As EventArgs)
    dgvdefault.Refresh()
    RemoveHandler timer1.Tick, AddressOf timer1_tick
End Sub