滚动完成后刷新绘画

时间:2015-04-21 08:49:37

标签: vb.net winforms scroll datagridview paint

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

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

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

以下是我的代码,不确定它是否与show相关,但现在是。

    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

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

正确的不是最好的答案,但这就是我想要让我的dgv刷新后滚动,这看起来效果很好(非常少的延迟)。

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