You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET中调整DataGridView滚动行为:设置每次滚动1行

调整DataGridView每次滚动1行的平滑实现方案

方法1:直接处理MouseWheel事件(无需自定义控件)

这种方案无需修改控件源码,直接在窗体中处理鼠标滚轮事件,取消默认的3行滚动行为,手动控制每次滚动1行,流畅度和稳定性更好。

Private Sub DataGridView1_MouseWheel(sender As Object, e As MouseEventArgs) Handles DataGridView1.MouseWheel
    ' 取消默认滚动逻辑
    DirectCast(e, HandledMouseEventArgs).Handled = True

    ' 根据滚轮方向确定滚动方向:向上滚-1行,向下滚+1行
    Dim scrollOffset As Integer = If(e.Delta > 0, -1, 1)
    Dim targetRowIndex As Integer = DataGridView1.FirstDisplayedScrollingRowIndex + scrollOffset

    ' 限制行索引在有效范围内,避免越界
    targetRowIndex = Math.Max(0, Math.Min(targetRowIndex, DataGridView1.RowCount - DataGridView1.DisplayedRowCount(False)))

    ' 设置新的滚动起始行,此属性仅控制滚动位置,不会触发单元格选中等额外操作
    If targetRowIndex >= 0 Then
        DataGridView1.FirstDisplayedScrollingRowIndex = targetRowIndex
    End If
End Sub

关键说明

  • 不要使用FirstDisplayedCell控制滚动:该属性会触发单元格选中事件,导致界面闪烁、行为不稳定;FirstDisplayedScrollingRowIndex是专门用于控制滚动位置的属性,无额外副作用。
  • 边界判断必须加:避免滚动到数据范围外引发异常。

方法2:自定义DataGridView控件(全局彻底处理)

如果需要在多个窗体复用该滚动行为,或要同时处理键盘上下键的滚动(默认也是3行),可以继承DataGridView重写底层消息处理逻辑:

Public Class CustomDataGridView
    Inherits DataGridView

    Protected Overrides Sub WndProc(ByRef m As Message)
        ' 处理鼠标滚轮消息(WM_MOUSEWHEEL)
        If m.Msg = &H20A Then
            Dim delta As Integer = CInt(m.WParam) >> 16
            Dim scrollOffset As Integer = If(delta > 0, -1, 1)
            UpdateScrollPosition(scrollOffset)
            m.Result = IntPtr.Zero
            Return
        End If

        ' 处理键盘上下键滚动消息(WM_VSCROLL,可选)
        If m.Msg = &H115 Then
            Dim scrollCmd As Integer = CInt(m.WParam) And &HFFFF
            ' SB_LINEUP(0)=上滚一行,SB_LINEDOWN(1)=下滚一行
            If scrollCmd = 0 Or scrollCmd = 1 Then
                Dim scrollOffset As Integer = If(scrollCmd = 0, -1, 1)
                UpdateScrollPosition(scrollOffset)
                m.Result = IntPtr.Zero
                Return
            End If
        End If

        ' 其他消息交给默认逻辑处理
        MyBase.WndProc(m)
    End Sub

    Private Sub UpdateScrollPosition(scrollOffset As Integer)
        Dim targetRowIndex As Integer = Me.FirstDisplayedScrollingRowIndex + scrollOffset
        targetRowIndex = Math.Max(0, Math.Min(targetRowIndex, Me.RowCount - Me.DisplayedRowCount(False)))
        If targetRowIndex >= 0 Then
            Me.FirstDisplayedScrollingRowIndex = targetRowIndex
        End If
    End Sub
End Class

关键说明

  • 该方案直接拦截底层Windows消息,行为更稳定,无事件延迟问题;
  • 可选处理键盘上下键滚动,让键盘操作也遵循每次1行的规则;
  • 若有冻结行,需调整targetRowIndex的计算逻辑,避免滚动冻结区域。

内容的提问来源于stack exchange,提问作者Tesla96

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 12:33:18