Problem with derivated forms and anchored controls

  • Thread starter Thread starter davy
  • Start date Start date
D

davy

I've made one form which has a private button control.
I've changed the anchor property of the button control to bottom
right.
I've created a new form derived from the first one and I resize it in
the designer. The button control remains anchored correctly and the
position on the form changes when I change the size of the form (which
is correct).
If I save and reload the derived form in this stage the control is
still in the position where it was when I saved the form (also this is
correct).
Now, I add a new control on the derived form, and save the form. When
I reload the form in the designer the first control is in the position
where it was on the base form (which is not correct anymore).
The change that the designer made in the derived form
InitializeComponent() method is that it added SuspendLayout() and
ResumeLayout(), if I remove those method calls all is right again, but
the designer will regenerate the code on the next save, so is not a
solution.

Does anyone know a workaround to this problem? (I need that first
control remains private and bottom right anchored).
 
davy said:
I've made one form which has a private button control.
I've changed the anchor property of the button control to bottom
right.
I've created a new form derived from the first one and I resize it in
the designer. The button control remains anchored correctly and the
position on the form changes when I change the size of the form (which
is correct).
If I save and reload the derived form in this stage the control is
still in the position where it was when I saved the form (also this is
correct).
Now, I add a new control on the derived form, and save the form. When
I reload the form in the designer the first control is in the position
where it was on the base form (which is not correct anymore).
The change that the designer made in the derived form
InitializeComponent() method is that it added SuspendLayout() and
ResumeLayout(), if I remove those method calls all is right again, but
the designer will regenerate the code on the next save, so is not a
solution.

Does anyone know a workaround to this problem? (I need that first
control remains private and bottom right anchored).

I've had problems like this, but they occurred on the next build, not the
next save. Are you sure it doesn't happen when you build while the designer
is still open?
 
I've had problems like this, but they occurred on the next build, not the
next save. Are you sure it doesn't happen when you build while the designer
is still open?

Actually is happening every time the derived form is loaded in the
designer. You need to close the form and reopen it or rebuild the
project to signal the designer to reload the form.

Anyway, I am almost sure the problem appear because a bug in the
suspend/resume layout logic. I've found many problems with this logic,
first was that when layout is suspended the Size property is not
modified if ClientSize property of the form changes. I suppose that
this was the intention of those who wrote that code, but this behavior
introduces many problems, especially because most of the code use Size
property not ClientSize property.

When I tried to find a workaround to my problem, the main idea was to
get rid of the suspend/resume behavior. I could not do it modifying
the code in the InitializeComponent() so I've tried to overload the
SuspendLayout() and not calling the base method. Although this work at
run time it doesn't work in the designer, that because the
SuspendLayout() is not a virtual function and the designer seams to
use Form.SuspendLayout().

I'm not sure that this is the way in which the designer works, is just
an assumption, but I think when the designer loads the derived form it
instantiate the base form and then using a Form reference of the
instantiated object calls all the functions in the
InitializeComponent(). In my opinion the correct approach will be to
create a derived class (not to use the class in the designer, because
it may not be compilable), having just control definitions and
InitializeComponent() method, compile it and use it instead of the
base class when load the form in the designer. This will help in other
situations too, like when using an abstract base class, but this will
be a little more complicated.

In the end I want to say that the only workaround that made possible
not to throw all I've worked for one week was to do something like
this in the base form:

protected override void SetClientSizeCore(int x, int y)
{
ResumeLayout(false);
base.SetClientSizeCore (x, y);
}

I hope this will help someone, although I know is not a solution.
 
Back
Top