views:

2503

answers:

2

Hiya - been pointed at you guys by a friend of mine.

I have an MDI application (C#, Winforms, .NET 2.0, VS2005, DevExpress 8.2) and one of my forms is behaving very strangely - not repainting itself properly where it overlaps with another instance of the same form class.

The forms contain a custom control (which contains various DevExpress controls), and are inherited from a base form (which is itself inherited).

Due to issues with form inheritance (that old chestnut) there is a bit of control rearranging going on in the constructor.

Problem 1 (minor): None of this control repositioning/resizing seems to take effect unless the form is resized, so I nudge the width up and down by one pixel after the rearranging. Ugly, hacky and I'd really like to not have to do this.

Problem 2 (major): If forms are shown then attached to the MDI form using the API call SetParent, when I display the 2nd instance, various parts of the two forms are not correctly drawn where they overlap - bits of the top one are behind the existing one - and this problem gets worse when the forms are moved around, rendering them basically unuseable. Other child forms (if present) of a different type seem unaffected...

STOP PRESS: I've established that it doesn't have to be 2 instances of the child form. With only one there are still problems - mainly round the edges of the form, like the area that's being refreshed is smaller than the form itself.

The problem does not occur if the parent is set using the .MDIParent property of the child form - but we cannot do this as the form may be being displayed by a control hosted in a non-.Net application. Also I need to display the child forms non-maximised even if the existing children (of a different type) are maximised, and that only happens using SetParent.

I have tried Refresh() on all the forms of this type (I have a controller that keeps a list of them), but no joy. I have tried to reproduce this effect form a basic app with the same inheritance structure, but I can't. Clearly it is something about the form - since I recreated the form from scratch yesterday and it is still the same it must be the code - but what??

I am not the hottest on form painting events etc. so have I missed something?

A: 

Ah ha!

I was changing the FormBorderStyle in code before showing the form. I removed that line and the problem went away...

That'll do for me. :-)

kpollock
+1  A: 

Yes, that would do it. Changing the FormBorderStyle requires Windows Forms to recreate the window from scratch, now using different style flags in the CreateWindowEx() call. That would make it completely forget about the parent you set with the SetParent() P/Invoke. There are lots of other properties that causes this to happen. Avoid the kind of trouble you got into by making these calls in an override of the OnHandleCreated() method.

Better yet, avoid troublesome APIs like SetParent() completely by putting all your controls and logic in a UserControl.

Hans Passant
I'd love to ditch the MDI but we are stuck with it (and hence using SetParent for the reasons mentioned above). A complication that I omitted is that the UserControl that invokes the form can also be within a Powerbuilder MDI, so it has to be SetParent (at least in that case).
kpollock