Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Hi,

I'm developing a class derived from Panel Control. It's Transparent, moveable and resizeable. When moving or resizing (onMouseMove event) it draws a Temperory rectangle over the parent control. I

Adding a single control to a form from this class isn't a problem. But when I add multiple controls on a form I have a problem. If I move a control the others that are added later are not painted. Let's say I have 3 controls If I move the third one everything is normal. If I move the second one the third doesn't paint during movement. If I move the first one the second and third don't paint.. After the movement everything comes back.

I think the problem is my later added controls doesn't receive painting calls. I wonder is there a hierarchy according to adding order of controls.

 

Thanks advance.

Posted

Hi there,

 

First of all WinForms doesn't support real transparency. An image is created in the paint event from the colors beneath the object and uses that as it's background. So WinForms might have some paint-problems if you use several transparent object drawn on eachother.

 

Secondly if your mousemove keeps calling there might be no time left for repainting before your next mousemove call.

 

If you still encounter problems please post some code, and we'll see what we can do :)

 

~ DP

My Development System

Intel Core i7 920 @2.66Ghz

6 GB DDR3 SDRAM

Windows 7 Ultimate x64 & Windows Vista Home Premium x64 dual boot

GeForce GTX295 1.8 GB

3.5 TB HD

Posted

Thanks for comment.

But actually my problem is not just transparency. While a control is drawing a rectangle on parent form another controls that are added after this are not painted.

 

My code looks like this

 

public class MyControl : Panel

 

{

 

public MyControl()

 

{

SetStyle(ControlStyles.SupportsTransparentBackColor, true);

SetStyle(ControlStyles.Opaque, true);

this.SetStyle( ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint ,true);

}

 

protected override void OnPaint(PaintEventArgs e)

 

{

// Draw some graphics on this object

// Graphics g= e.Graphics

// ...................

 

if (IsSMoving)

{

Graphics g2 = this.Parent.CreateGraphics();

 

// g2.DrawRectangle(); Here we draw a temporary rectangle on parent (Form)

this.Parent.Invoke();

}

base.OnPaint(e);

 

}

 

}

}

 

____________________________

 

On a form I add some objects from this class. But if a control is moving the ones added later are not shown until it stops moving.

Posted

try to trace some messages in the Paint handling code

ie.

Trace.WriteLine("panel" & id & "painted!");

 

where you give each panel a temporary id.

this way you can determine in your immediate window if your panel gets its paint event. if it does you can step through your code with a breakpoint under the condition that the id matches the third or second panel. This way your breakpoint only breaks on paint events of your 'incorrect' panels. Please share your results.

 

~DP

My Development System

Intel Core i7 920 @2.66Ghz

6 GB DDR3 SDRAM

Windows 7 Ultimate x64 & Windows Vista Home Premium x64 dual boot

GeForce GTX295 1.8 GB

3.5 TB HD

Posted

Thanks for answer.

 

I put Debug.WriteLine (this.name + "painted" ) ;

in paint event.

 

If I move the first added control the output is:

c1 painted

c1 painted

c1 painted

.............

c1 painted

c2 painted

c3 painted

 

if I move the second added one the output is

c2 painted

c1 painted

c2 painted

c1 painted

..............

c2 painted

c1 painted

c3 painted

 

 

if I move the last added (third control)

c3 painted

c1 painted

c2 painted

..........

c3 painted

c2 painted

c1 painted

 

 

So, each control prevents the painting of other controls. Now I realized that The problem is about this.Parent.Invoke() method. In each paint event my control paints a graph on parent and calls this method. The parent calls the control paint methods in a queue and when it reaches the current control, it receives the invoke call and starts from the first control again.

The question is how can I prevent this endless loop while I can paint something on parent control.

 

Thanks

Posted
Why I'm setting Opaque, just because to find a solution. I know it's not a clever way. Otherwise only the first control is painted. But I need to find a solution for parent -> child , child >parent endless Invalidate() calls.
  • Leaders
Posted
There is something fundamentally wrong with your method if yau are getting this recursion. It seems to me that a control shouldn't be drawing to anything but itself in the Paint event. I'm not sure exactly what you are trying to achieve.
[sIGPIC]e[/sIGPIC]
Posted

It may be wrong but I was trying to draw a temporary rectangle over the parent control during movement and resizing events. The temporary rectangle is drawn on parent control and onMouseUp my control places itself on this rectangle. Actually if you have a better solution please help me.

Thanks.

  • Leaders
Posted

Maybe the control can handle its parent's paint event and do the rectangle drawing there. To do this you would have to explicitly invalidate the parent whenever the rectangle moves, and the result may not necessarily look that good.

 

You could also try to draw the rectangle outside of the paint event, but if your control is transparent it wont look right when they overlap.

[sIGPIC]e[/sIGPIC]
Posted
Thanks a lot. If I invalidate the parent it tries to draw itself and the childs whatever parameter I pass to Invalidate() method. This causes my control call the parent invlidate() againd which starts the problem
  • Leaders
Posted

It seems to me that you don't have a great handle on the way that control painting works. I understand that it's not that simple. Consider these tips.

 

Your control should not be invalidating anything while it is painting, especially its parent. Painting is the result of invalidation, and not vice-versa.

 

A control should not be drawing to anything but its own client region using the provided graphics object when painting.

 

You should not explicitly invoke the Paint event or the OnPaint method. Windows will invoke these for you when a control is invalidated.

 

You should only be invalidating a control when its visual state does not represent it's logical state (i.e. it is invalid, and therefore should be painted). A control should not invalidate its chrilden. Windows does this for you automatically.

[sIGPIC]e[/sIGPIC]

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...