滚动完成后刷新画图
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
我有一个数据网格视图,它在选定的单元格周围放置了一个黑色边框。我的代码工作正常,直到我在进行选择时滚动。当我在进行选择时向下滚动时我的顶部边框消失了,这在这一点上不是问题,因为它表明有更多选定的单元格不在视图中,我遇到的问题是一旦我做出选择然后 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