Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

During FlowLayoutPanel scrolling, background distorts + flickers

I have a windows form application that has a background. Within it, I have a flowlayoutpanel with a transparent background. When I scroll, the following happens:

enter image description here

I also see some flickering. I've tried all the doublebuffered business, and it doesn't work.

Any suggestions?

like image 825
Andy Hin Avatar asked Jul 27 '10 05:07

Andy Hin


5 Answers

this is what worked for me.

public class CustomFlowLayoutPanel : FlowLayoutPanel
{
    public CustomFlowLayoutPanel()
        : base()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    }

    protected override void OnScroll(ScrollEventArgs se)
    {
        this.Invalidate();

        base.OnScroll(se);
    }
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x02000000; // WS_CLIPCHILDREN
            return cp;
        }
    }
}
like image 199
MajinFro Avatar answered Nov 02 '22 10:11

MajinFro


Yeah, that doesn't work. Here's a class that improves it somewhat:

using System;
using System.Windows.Forms;

class MyFlowLayoutPanel : FlowLayoutPanel {
    public MyFlowLayoutPanel() {
        this.DoubleBuffered = true;
    }
    protected override void OnScroll(ScrollEventArgs se) {
        this.Invalidate();
        base.OnScroll(se);
    }
}

Compile and drop it from the top of the toolbox onto your form. It however cannot fix the fundamental problem, the "Show window content while dragging" option. That's a system option, it will be turned on for later versions of Windows. When it is on, Windows itselfs scrolls the content of the panel, then asks the app to draw the part that was revealed by the scroll. The OnScroll method overrides that, ensuring that the entire window is repainted to keep the background image in place. The end-result is not pretty, you'll see the image doing the "pogo", jumping up and down while scrolling.

The only fix for this is turning the system option off. That's not a practical fix, users like the option and it affects every program, not just yours. If you can't live with the pogo then you'll have to give up on the transparency.

like image 11
Hans Passant Avatar answered Nov 02 '22 11:11

Hans Passant


I am very pleased to report that Hans, and the internet at large (just learn WPF....pfffft), is wrong here.

The problem is in the WM_HSCROLL and WM_VSCROLL events. Through some trial and error, I found that, if I dragged the scroll bar fast enough, I was able to move a ghost copy of my background over the actual background which was fxied how I wanted it. So whatever is happening inside the scrollable control, Windows is able to keep up and some out of sync redraw is what's causing the shearing.

So how do you solve this problem?

  1. Set your scrollable control to DoubleBuffered.

  2. Catch the WM_HSCROLL/WM_VSCROLL messages. Invalidate. Set the "do_not_paint" flag to true. Call the base.WndProc(). Set the "do_not_paint" flag to false. Update.

  3. Catch the WM_PAINT and related messages. Only call base.WndProc() if the "do_not_paint" flag is false.

What this does is allow the scrollable control to do whatever layout calculations and scrollbar repositioning it needs to do but doesn't let it redraw anything that would trigger the shearing effect.

like image 3
Ryan Killian Avatar answered Nov 02 '22 10:11

Ryan Killian


I added Application.DoEvents() to the Scroll event of the FlowPanel amd that stopped the blurring of the FlowPanel child controls that I was getting.

like image 2
user3165730 Avatar answered Nov 02 '22 10:11

user3165730


It´s a little bit late ... but this things happen if you mess with Color.Transparent. Check if your FlowLayoutPanel has Transparent Background. If so, try to change that.

like image 1
André Fiedler Avatar answered Nov 02 '22 10:11

André Fiedler