Control MouseWheel Scrolling

ALX

Well-known member
Joined
Nov 16, 2005
Messages
253
Location
Columbia, SC
Programming Experience
10+
I'm trying to limit the number of rows that are scrolled with each mouse wheel indent on a Data Grid View as it displays thumbnail bitmaps. The standard 3 rows is disorienting for the user and I'd like it to resemble Windows Explorer when scrolling through thumbnails at 1 row per indent. I've tried to do my homework and came up with the following ridiculous code below which of course doesn't work at all...

VB.NET:
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
    Protected Overrides Sub WndProc(ByRef m As Message)

        If (m.Msg = &H20A) Then
            If CInt(m.WParam) < 0 Then
                SendKeys.Send("{DOWN}")
            ElseIf CInt(m.WParam) > 0 Then
                SendKeys.Send("{UP}")
            End If
        Else
            MyBase.WndProc(m)
        End If
    End Sub

Apparently there are no quick & dirty ways to do this by handling the MouseWheel event since the MouseEventArgs does not have a ".handled" property to set. It seems I need to set up a WndProc listener and handle the wheel event by sending UP & DOWN keys to the DGV. I know this does not consider the wheelDelta value. I'm still trying to get this to trap the MouseWheel event.
 
In MouseWheel event cast MouseEventArgs to HandledMouseEventArgs and set .Handled to True, then use DGV.FirstDisplayedScrollingRowIndex to implement scrolling. e.Delta is positive or negative for scrolling direction.
 
Thanks John: I looked at that earlier and had trouble getting it to work because I was using the wrong syntax. When I read "cast MouseEventArgs to HandledMouseEventArgs", I did just that:
VB.NET:
 Private Sub DGV_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DGV.MouseWheel

        e = DirectCast(e, HandledMouseEventArgs)
...
Then of course, I still had no .handled property.
For anyone who might need to know, or offer a better way, the following snippet works ;)
VB.NET:
Private Sub DGV_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DGV.MouseWheel

        Dim Ex As HandledMouseEventArgs = CType(e, HandledMouseEventArgs)
        Dim currentIndex As Integer = Me.DGV.FirstDisplayedScrollingRowIndex

        Ex.Handled = True

        Select Case e.Delta
            Case 120 'Scrolling up
               DGV.FirstDisplayedScrollingRowIndex = Math.Max(0, currentIndex - 1)

            Case -120 'Scrolling down
                DGV.FirstDisplayedScrollingRowIndex = currentIndex + 1
        End Select
    End Sub
 
e = DirectCast(e, HandledMouseEventArgs)
e variable here is still declared as type MouseEventArgs here, so the value you assign to it is implicitly cast back as that type.
Dim Ex As HandledMouseEventArgs = CType(e, HandledMouseEventArgs)
Correct, but with type inference you don't need to declare the variable type, it will be inferred by the type of assigned value. You can also simplify:
CType(e, HandledMouseEventArgs).Handled = True

By the way, CType will do the same as DirectCast when no conversion is needed, DirectCast will only cast type when possible and will not do conversions.
 
CType will do the same as DirectCast when no conversion is needed, DirectCast will only cast type when possible and will not do conversions.

'Something I've always wondered about. This is the stuff the books don't tell you.
Thanks John.
 
Back
Top