Re: TSplitter Persistence problem



samjones wrote:
I have a form setup with 3 Panels and 2 Splitters as follows:

Panel3
Splitter2
Panel2
Splitter1
Panel1

Everything is alBottom aligned except Panel3 which is aligned alClient.

At FormClose I save Panel1.Height and Panel2.Height and at FormCreate I restore these 2 values.

Problem is, if I execute the program and move say Splitter2 up some then Close the Form and Reopen it, I get the following:

Panel3
Splitter2
Splitter1
Panel2
Panel1

It looks like the controls are maybe loosing their index locations.

No, array indices have nothing to do with it. Instead, it's that Delphi uses a control's coordinates to determine whether it's above or below any other controls, and when the coordinates are incorrect temporarily, an intermediate problem can become a persistent one.


Merely changing the size of a control won't necessary affect the sizes and positions of the rest of the controls as the form gets created. I know visibility of the container has something to do with it -- resizing each control one at a time while the form is visible would probably solve your problem, but let's see if we can come up with a better solution before resorting to that.

First of all, make sure you change the height of Panel1 before you resize Panel2; Panel2's Align property is set such that it depends on Panel1 for one of its coordinates.

After to resize Panel1, adjust the location of Splitter1. You could be exact about it and set it like this:

Splitter1.Top := Panel1.Top - Splitter1.Height;

I'm lazy, though, so I'd just set it like the following and let the form's aligner do the rest.

Splitter1.Top := Panel1.Top - 1;

Then, adjust Panel2 and Splitter2 the same way. Take care that there's still room for Panel3 in there somewhere. Weird things will probably happen if Splitter2 somehow ends up above Panel3.

I've also noticed weird things happen if the size of anything under a splitter's control is zero. The splitter would end up on the wrong side of the control. In that case, I handled one of the splitter's events (OnCanResize or OnMoved -- I don't remember which) and explicitly moved the control to the correct side of the splitter, again by specifying a coordinate +/-1 from the splitter's own coordinate.

--
Rob
.