我有一个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
答案 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