2

I have a Winform user control that is flickering really bad. The functionality of the control is working just perfectly. Its just flickering really bad. I am doing all the drawing onto a bitmap then using DrawImage to just copy the bitmap onto the screen, so I am surprised by how much flickering is occurring. Here is an excerpt of what I have:

    private void ScrollPanel_Paint(object sender, PaintEventArgs e)
    {
        var c = (Calendar)Parent;

        Bitmap bmp = c.RequestImage();
        if (bmp == null)
            return;

        e.Graphics.DrawImage(bmp, new Rectangle(0, 0, ClientSize.Width, ClientSize.Height),
                             new Rectangle(0, _scrollOffset, ClientSize.Width, ClientSize.Height),
                             GraphicsUnit.Pixel);
        _bmpSize = bmp.Height;
        e.Graphics.Dispose();
        bmp.Dispose();
    }

    private void ScrollPanel_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            _mouseDown = true;
            _oldMouseCoords = e.Location;
        }
    }

    private void ScrollPanel_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
            _mouseDown = false;
    }

    private void ScrollPanel_MouseMove(object sender, MouseEventArgs e)
    {
        if (_mouseDown && e.Location.Y < _oldMouseCoords.Y && _scrollOffset < _bmpSize - _scrollOffset - ClientSize.Height)
        {
            int offset = _oldMouseCoords.Y - e.Location.Y;
            _scrollOffset += offset;
            Refresh();
        }
        if (_mouseDown && e.Location.Y > _oldMouseCoords.Y && _scrollOffset > 0)
        {
            int offset = e.Location.Y - _oldMouseCoords.Y;
            _scrollOffset -= offset;
            Refresh();
        }
        _oldMouseCoords = e.Location;
    }

What its supposed to be doing is, when I drag with my mouse, it should be scrolling the bitmap, which it is. Like I said, the functionality is all working. As you can see from the Paint event, all I'm doing is acquiring my bitmap then copying it directly to the screen.

Any help would be appreciated.

Icemanind
  • 47,519
  • 50
  • 171
  • 296
  • 1
    Try setting the form's property DoubleBuffered to true – SimpleVar May 03 '12 at 01:05
  • Yorye -- I tried that, but anytime I do that in a Winform application, I always get an error at runtime that says `Invalid Parameter` – Icemanind May 03 '12 at 01:12
  • 1
    I don't think you should be calling `Dispose()` on the `Graphics` object... it's not yours to dispose, and the control probably still needs it after you've finished painting. – Bradley Smith May 03 '12 at 01:18
  • Yeah Bradley. That is correct. I removed the Dispose() call on the graphic object and now I can DoubleBuffer it. – Icemanind May 03 '12 at 01:28
  • Yorye -- Doublebuffering it fixed my flicker problem. Make your comment into an answer and I will make it as correct. – Icemanind May 03 '12 at 01:28

1 Answers1

3

Take a look at this other question about double-buffering, to make sure you're setting that up correctly... Enabling Double Buffering

In my experience, once double-buffering is set up, flickering is caused by the control's background being painted, even though you've chosen to do all painting yourself. I've avoided this by deriving my own control class from the one being painted, overriding the OnPaintBackground method, and NOT calling the base class implementation in that method.

So in your case, I assume that ScrollPanel is a Panel. I would derive a class from Panel, and use that instead of Panel. Then I would override OnPaintBackground, and leave the body of that method empty.

Having done all that, I got scrolling that's just about as smooth as WinForms can achieve.

Community
  • 1
  • 1
Martin
  • 5,392
  • 30
  • 39