0
votes

I am using the DataGridView and the scrolling behavior is very bad. It works very well when scrolling by moving the scrollbar on the side, but is extremely slow and freezes UI for several seconds when fast scrolling with the mouse.

Existing questions I found suggest setting DoubleBuffered property but it doesn't affect performance in my case as drawing is already fast when I move the scrollbar manually. The problem is only with scrolling with the mouse wheel.

1
So did you set DoubleBuffered or didn't you? - TaW
I did. As I said in question it doesn't affect performance in my case. - Kuba
Also the drawing itself is fast. It's the mouse wheel scrolling that is causing the slowdown in my case. Here is a screenshot of difference before (right) and after (left) applying my solution. i.gyazo.com/9c4a96c118e54e095c744680b9f42d4c.mp4 - Kuba
I wish you got an answer for this as it's the exact same issue i am having now and simply cannot find a solution. I've tried the answer given here and it doesn't work in vb.net. I have tried the EnableDoubleBuffering but that didn't help. Scrolling by dragging the scroll bar is perfect but with the mousewheel its horrendous. - Pete
Hi, Unfortunately I don't have anything to add except of my answer below. Since then I am very happy with performance of DataGridView. I don't know anything about VB and why something from C# wouldn't work there. - Kuba

1 Answers

0
votes

Solution is to handle WndProc of mouse wheel event before the control has the chance to handle it and simply change the FirstDisplayedScrollingRowIndex property.

public class FastScrollingDataGridView : DataGridView
{
    private int numberOfRowsPerScroll = 20;

    short GET_WHEEL_DELTA_WPARAM(IntPtr wParam)
    {
        var int32 = (int)wParam.ToInt64();
        var shifted = int32 >> 16;
        return (short)shifted;
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x20a) //WM_MOUSEWHEEL = 0x20a
        {
            var zDelta = GET_WHEEL_DELTA_WPARAM(m.WParam) > 0 ? numberOfRowsPerScroll : -numberOfRowsPerScroll;
            var newValue = FirstDisplayedScrollingRowIndex - zDelta;
            if (newValue < 0) newValue = 0;
            this.FirstDisplayedScrollingRowIndex = newValue;
            return; 
        }
        base.WndProc(ref m);
    }
}