tags:

views:

1949

answers:

7

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.

+1  A: 

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.

rice
+1 because you alerted me to the ImageAnimator class which is useful for another project of mine.
Ed Swangren
A: 

Long shot, but have you tried

SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

On the Panel Control?

KiwiBastard
+2  A: 

Set DoubleBuffered = true on the form.

mannu
A: 

I have tried the .NET double buffering implementation, as well as my own. Not any real difference there. It is definitely better than not using double-buffering at all, but there is still some flicker.

@rice: I will look into the ImageAnimator class, thanks.

Ed Swangren
A: 

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.

Craig
This is the double-buffering method that I have been using.
Ed Swangren
+1  A: 

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

Mark Allen
+4  A: 

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.

Ed Swangren