Ed Swangren
Ed Swangren

Reputation: 124642

How to avoid screen flickering when a control must be constantly repainted in C#?

I have a simple panel that is used as a drawing surface. The goal here is to draw a 4 pixel wide outline around a child ListView under certain circumstances. I would like to make the outline pulsate when something can be dragged into it.

I am just drawing a simple rectangle around the ListView and updating the opacity of the rectangle inside of a timer tick event. When the opacity is changed, the border is re-drawn. I am double-buffering the painting at this point. I am also only allowing a redraw every 15 ticks or so (the timer interval is 20 ms). After all of this, the drawing process still flickers a bit. This is not acceptable, so I need some guidance on how I could avoid this.

I don't see a way around painting the control quite often. There needs to be a smooth transition from opaque to solid and back again. When I lower the tick interval enough (down to about 300 -500 ms), the flashing stops, but the refresh rate is too slow.

I am open to any and all ideas. Perhaps the way I am approaching this is just plain wrong, or perhaps one of you have already created a glow effect and know what to do. Thanks for any help in advance.

Upvotes: 3

Views: 7279

Answers (6)

Ed Swangren
Ed Swangren

Reputation: 124642

I stumbled on a solution for this if anyone is interested. It turns out that the flashing is caused by the painting of the background. I used SetStyle to tell the control that I will be handling all of the painting.

SetStyle(ControlStyles.SupportsTransparentBackColor |
         ControlStyles.Opaque |
         ControlStyles.UserPaint |
         ControlStyles.AllPaintingInWmPaint, true);

I then first paint a transparent color over the region, and then I paint my border. I bit of a hack, but it works like a charm.

EDIT: And remember to double buffer the image as well.

Upvotes: 4

Mark Allen
Mark Allen

Reputation: 1205

I'm sorry in advance that this likely won't help but: WPF has animations and could at least in theory do this smoothly.

Upvotes: 1

Craig
Craig

Reputation: 12012

You also may want to look at doing the drawing on a bitmap and then just displaying the bitmap if it has changed. Just my 2c.

Upvotes: 0

mannu
mannu

Reputation: 793

Set DoubleBuffered = true on the form.

Upvotes: 3

JamesSugrue
JamesSugrue

Reputation: 15011

Long shot, but have you tried

SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

On the Panel Control?

Upvotes: 0

rice
rice

Reputation: 1063

I don't have a strong answer, but since you have none, I'll post anyway:

First, I have never used the System.Drawing.ImageAnimator class, but could that be a better approach for you?

Second, if that fails, have you tried not using double-buffering? It's a long shot, but maybe your double-buffering code is actually making it worse.

Upvotes: 1

Related Questions