views:

427

answers:

2

I have a Control that can overlay multiple C# user controls in my GUI. This control has a semi-transparent background in order to 'grey-out' portions of the GUI and the class looks somethink like this:

public greyOutControl: UserControl
{
    // Usual stuff here

    protected overide OnPaint()
    {
        paintBackround();

        base.OnPaint();
    }
}

Currently the control sometimes gets caught in a loop and constantly re-draws the background, making the semi-transparent color appear less and less transparent.

My idea to combat this is the following (in broad terms):

1) Determine what controls the greyOutControl is on top of 2) call Refresh() on those controls to update the display 3) continue drawing the greyOutControl.

My question is: How can I determine which controls the greyOutControl overlaps?, or is there a way that I can refresh only the part of the GUI that greyOutControl covers?

A: 

I don't see a direct way of finding the overlapping controls. I think you might need to check the whole control tree to find out that. About refreshing, you can use Control.Invalidate(Rectangle) method to specify which part to refresh.

Mehrdad Afshari
The trouble with calling Invalidate() is that Invalidate is not guarenteed to be called immediatly, rather the documentation states that it will be called at the next convienient time. Within the OnPaint() function it is important to have the background render fully before attempting to add the semi-transparent overlay. Hence why Refresh() is preferred.
TK
+1  A: 

Why don't you keep track of your transparent controls and paint them after all the other controls are drawn?. Painting anything at the top of the Z-order shouldn't cause the other controls to be repainted.

Trap
Essentially I am only Showing / Hiding the transparent control when needed i.e. on top of all the other controls. The reason something more is required is due to the fact that the transparent portions of the control are re-painted multiple times causing an undesirable effect. Therefore whenever the Control is re-drawn I wanted it to be rendered fully with the correct transparent areas.
TK
Have you tried to not call base.OnPaint() ?
Trap
Currently I am custom rendering the background (i.e. the transparent parts) and I am letting the the c# library handle the rendering of all non-transparent parts of the control e.g. Buttons, Text etc. Im sure it would be possible to completely remove the call to base.OnPain, it is currently undesirable because of the increased workload.
TK
I'm not sure what could be happening in the base class, but probably the default behaviour might be to invalidate the whole control and causing OnPaint() being called over and over.
Trap