WinForms ReportViewer: mouse wheel scrolls two pages instead of one

I'm using a ReportViewer control in my WinForms application to display a RDLC report.

The form is etremely simple (it only has the reportviewer in it, and nothing else) and generally it works quite well.

But there is one annoying issue: when the user uses the mouse wheel to change the page, every scroll up/down goes two pages backwards/forwards, rather than one.

This makes reading the report very annoying, of course. Why is it doing this, and how can I make it scroll just one page?

EDIT: by testing further I can confirm that the ReportViewer's PageNavigation event fires twice for each "tick" of the scroll wheel. Still don't know why...

EDIT: The original stack trace appears to only be true if your application is running as 32-bit. In the case of 64-bit, there are only three lines in the second call that do not also appear in the first, which are listed here.

at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)

The updated code to handle both scenarios is

private void Viewer_PageNavigation(object sender, PageNavigationEventArgs e) => e.Cancel = Environment.StackTrace.Contains("DefWndProc");

This is still quite an ugly hack, but it is effective.


To see what's really going on here, you need to disable "Just My Code" and debug into the Framework. By subscribing to the ReportViewer.PageNavigation event and setting a breakpoint, you can see navigation occurring twice. The first time is triggered by a WM_MOUSEWHEEL message that is handled by a component of the ReportViewer called RenderingPanel. That component's OnMouseWheel method just calls ReportPanel.OnMouseWheel, which performs scroll/navigation. However, the same window message is then passed on to the ReportPanel, resulting in ReportPanel.OnMouseWheel being called again. Essentially, every low-level wheel message results in two scrolls. You can test this by breaking in ReportPanel.OnMouseWheel and setting e.Handled = true during the first call. In that case, a second call to ReportPanel.OnMouseWheel is not made.

Note that we are talking about mouse wheel events for internal components of the ReportViewer and this is not the same as the control's wheel event. Despite all of the internals, ReportViewer.MouseWheel is only raised once and that occurs after both PageNavigation events.

Bottom line here is that the control always processes the wheel message twice. Normally, you wouldn't notice this. If you wheel down and the report scrolls by 10%, how would you know that it was really only supposed to scroll by 5% but it actually scrolled twice? However, if your zoom level is sufficient so that a single wheel scroll equals a whole page then ... boom ... two pages per wheel scroll. I have not, however, gone so far as to determine why this is only an issue in print preview mode.

There's no clean fix for this. The best I came up with was to examine the stack inside of ReportViewer.PageNavigation and if the event is being caused by the RenderingPanel then ignore it. Such a fix looks like this:

/* The ReportViewer control is composed of several sub-controls. One of those is a RenderingPanel, whose OnMouseWheel method gets called
 * by the Framework in response to a window message. That method simply calls ReportPanel.OnMouseWheel, which performs scroll/navigation.
 * However, ReportPanel.OnMouseWheel is subsequently called again by the Framework in response to the same window message resulting in all
 * wheel events being processed twice. While this results in each wheel scroll being twice as large as it should be, it is generally not
 * noticeable (how would you know that the scroll distance should be half of what it is?) unless the zoom level is sufficient (i.e. Whole Page)
 * that a single wheel event results in an entire page navigation. In this case, two pages are flipped instead of one. In order to avoid this,
 * we simply cancel any page navigation that was caused by the RenderingPanel's handling of the wheel event. */    
private void Viewer_PageNavigation(object sender, PageNavigationEventArgs e) => e.Cancel = Environment.StackTrace.Contains("ReportPanel.RenderingPanel.OnMouseWheel");

ScrollableControl.AutoScroll Property (System.Windows.Forms , But there is one annoying issue: when the user uses the mouse wheel to change the page, every scroll up/down goes two pages backwards/forwards, rather  But there is one annoying issue: when the user uses the mouse wheel to change the page, every scroll up/down goes two pages backwards/forwards, rather than one. This makes reading the report very annoying, of course.

This is quite an interesting issue.

The ReportViewer's scroll trigger might use the paging from the normal displaymode, regardless on how it was defined. In this displaymode the reporter will only add page-breaks when specifically defined or add soft page-breaks determined by the InteractiveSize property.

You could set the InteractiveSize property the same as the PageSize which would allow you to use the DisplayMode.Normal and still keep the same page-breaking as in the DisplayMode.PrintLayout.

However this might still not fix the scrolling issue, because it's possible that the ReportViewer scrolling also ignores the soft pagebreaks. Which would mean that it's scrolling on a single page first, then afterwards apply the paging, and thus have the possibility of skipping a page. If this is the case, then I believe your only other option is to write your own custom version of the ReportViewer and try to fix it.


Edit: Turns out that the scroll behavior is working properly for me. This means that it has to be an issue specific to your environment. What version and frameworks are you using?

You can easily solve it by catching the scroll event and trigger the PageNavigation yourself.

winforms - Mouse Wheel Event (C, The following code example shows how horizontal and/or vertical scroll bars are You should see only an outline of the part of the text box that is outside the  I'm using the ReportViewer control in a WPF app. Everything works great however I want to disable the auto page advancing when the user scrolls down with the mouse wheel. I have the InteractiveSize set so paging is enforces. Perfect, however the user does not like scrolling down with the mouse wheel and automatically being advanced to the next

This is my solution, is in VB. It work with buttons navigation too.

First of all we must add handlers to the navigation buttons of report viewer. The name of my control reportviewer is "reportViewer"

Private Sub Print_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Dim ts As ToolStrip = TryCast(reportViewer.Controls.Find("toolstrip1", True).First, ToolStrip)
        If Not ts Is Nothing Then
            For Each tsb As ToolStripItem In ts.Items
                If TypeOf tsb Is ToolStripButton AndAlso
                (TryCast(tsb, ToolStripButton).Name = "firstPage" Or
                TryCast(tsb, ToolStripButton).Name = "lastPage" Or
                TryCast(tsb, ToolStripButton).Name = "previousPage" Or
                TryCast(tsb, ToolStripButton).Name = "nextPage") Then
                    AddHandler tsb.Click, AddressOf tsb_Click
                End If
            Next
        End If
End Sub

Then the core

Dim scrolled As New List(Of Integer)

Private Sub reportViewer_PageNavigation(sender As Object, e As PageNavigationEventArgs) Handles reportViewer.PageNavigation
    scrolled.Add(e.NewPage)
End Sub

Private Sub reportViewer_MouseWheel(sender As Object, e As MouseEventArgs) Handles reportViewer.MouseWheel
    If scrolled.Count > 1 Then
        reportViewer.CurrentPage = scrolled.Item(scrolled.Count - 2)
        scrolled.Clear()
    ElseIf scrolled.Count = 1 Then
        reportViewer.CurrentPage = scrolled.Item(scrolled.Count - 1)
        scrolled.Clear()
    End If
End Sub

Public Sub tsb_Click(ByVal sender As Object, ByVal e As EventArgs)
    scrolled.Clear()
End Sub

Hope this helps

How I disable vertical scroll bar of report viewer control on Web , One of the code snippets taken from the linked forum: using System c# - WinForms ReportViewer: mouse wheel scrolls two pages instead of o c# winforms  WinForms ReportViewer: mouse wheel scrolls two pages instead of one EDIT: The original stack trace appears to only be true if your application is running as 32-bit. In the case of 64-bit, there are only three lines in the second call that do not also appear in the first, which are listed here.

I have the same problem. The PageNavigation event fires twice each time I use the mouse wheel.

I resolve it customizing PageNavigation event:

    bool scroll = true;

    private void ReportViewer_PageNavigation(object sender, PageNavigationEventArgs e)
    {
        if (!scroll)
            e.Cancel = true;

        scroll = !scroll;
    }

Vertical ScrollBar In C#, I'm displaying .rdlc report file using Report viewer control on Webform. display one scrollbar on viewer control and second vertical scroll bar Solution 2 :- Add the below code on the bottom of the page after the </form> tag. One mouse wheel click or tick scrolls the datawindow one whole page down or up instead of 3 lines! Notepad and other applications are scrolling correctly, only PB Applications not. I think this is an issue. Or is there a datawindow or PB setting that could resolve this Problem? I uploaded two screen casts. 1. Recording_rdp.rar (Recording.avi

[Solved] ReportViewer Control Is not Visible in the Toolbox even if it , The Properties window looks like Figure 2. VScrollBar We can also use Width and Height property instead of Size property. The Dock The following code snippet adds an event handler for the Scroll event. vScroller.Scroll  With the mouse over the ChromiumWebBrowser control the parent "Scroller" responds to scroll wheel input. The web page also scrolls up and down This is incorrect - the parent scroller should scroll With the mouse not over the control - the control doesn't respond.

Display more than one page in Angular Report Viewer, 3) Scroll down the list, you should see two entries for Report Viewer. Make sure you tick the one for WinForms. 4) The ReportViewer control  WinForms ReportViewer: mouse wheel scrolls two pages instead of one EDIT: The original stack trace appears to only be true if your application is running as 32-bit. In the case of 64-bit, there are only three lines in the second call that do not also appear in the first, which are listed here.

When in Print Preview, allow the user to view more than one page at a time. Maybe using the zoom out or mouse wheel to show more and  4 C# : Application crashes after clicking Refresh button in ReportViewer a few times May 16 '17 1 How to convert from EBCDIC to ASCII in C#.net Aug 21 '18 1 WinForms ReportViewer: mouse wheel scrolls two pages instead of one Sep 4 '19

Comments
  • This sounds like your user needs to get a new mouse. But, maybe you can try to change report viewer display mode and see what happens: myViewerName.SetDisplayMode(DisplayMode.Normal); vs. myViewerName.SetDisplayMode(DisplayMode.PrintLayout)
  • The mouse is fine, it scrolls the canonical 120 points at each "tick" of the wheel. The ReportViewer is indeed set to Print mode, but that is how I want it... why should it jump over every other page when in print mode? Doesn't sound like the standard behavior to me...
  • it was just shot in the dark. I noticed that scrolling behaves differently in PrintLayout mode. I haven't experienced your problem though, and it doesn't look like other people did. Another thing to look into - InteractiveHeight of the report. Apparently, it's being set to 0 by default for long scrolling (whatever that means).
  • Just a heads up: I had time to test this, and it didn't work for me, since I don't have ReportPanel.RenderingPanel.OnMouseWheel in either of the events. However, by comparing the stack traces of the two events I discovered I have NativeWindow.DefWndProc only in the second one, so I used that to perform a similar check and all seems to work correctly. I don't exactly know why the difference is there, but it's worth noting that at the moment I'm hosting the ReportViewer inside a WPF app (using the WindowsFormsHost control) so that might change the calls stack in some way.
  • Interesting. What is the version number of your Microsoft.ReportViewer.Winform.dll? We have 13.0.1601.5. My first guess is possible function change between versions. Incidentally, we are also hosting the control in a WPF applcation.
  • mine is 15.0.0.0
  • I tried this in a brand new test project with version 15.0.0.0 and have the same result as before. Not sure what could be different.
  • Figured out the difference. 32-bit applications have the trace I mentioned originally while 64-bit apps have the trace you discovered. I have updated the answer accordingly.
  • My interactiveSize is already the same as the PageSize. I already have a "hacky" workaround, I will post it if no one else comes up with a "proper" solution. The weird thing is that I can find no one complaining about this online, so I assume it only happens in my reports? Don't know why...
  • I've just checked it for me, and I don't have the issue at all.(normal and print layout). So I believe this isn't a global issue.
  • @Master_T I was wondering if you still have the code for your workaround and could share it please? I am also seeing the issue with the mouse wheel scrolling the report two pages at a time.
  • @Krondorian: I'm afraid not, it was a long time ago and I don't even work for that company anymore... can't help you, sorry. All I remember is the fix involved catching the page changed event and performing some simple logic based on the direction of the scroll and the current position (to catch edge cases like first/last page) and then resetting the page number manually.
  • I am also seeing the problem with the mouse wheel action causing two pages to scroll at once. I downvoted this answer because when I tried customizing the event handler myself, as a side-effect it also affects page navigation using the page up and page down keys on the keyboard (which are unaffected by the mouse wheel double page issue.) It's a "fix one thing, break another" kind of hack.