Why is my TSplitter in the wrong place?
Asked Answered
M

3

5

I've got a dialog that's laid out something like this:

---------------------------------------------
|                                           |
| CONFIG AREA                               |
| Align: alTop                              |
--------------------------------------------- <-static boundary
|                                           |
| DISPLAY AREA 1                            |
| Align: alTop                              |
============================================= <-TSplitter Align: alTop
|                                           |
| DISPLAY AREA 2                            |
| align: alClient                           |
--------------------------------------------- <-bottom of dialog

However, at runtime, the splitter doesn't show up between Display Area 1 and Display Area 2, but between Config Area and Display Area 1, leading to some annoying interface problems. There's nothing in the form's setup-related event handlers that alters the Visible or Align properties of any of these components. Does anyone know why the splitter isn't loading in the place it's positioned at in the form designer?

Magnanimity answered 11/3, 2011 at 18:37 Comment(2)
From what you are showing, it should work as expected. Only thing that comes to mind are constraints, margins (if auto size with margins to true) and the splitter's MinSize property. I recently had all sorts of fun with form's growing unexpectedly because a splitter's MinSize got "honoured" at the wrong time. I'd check that the Splitters MinSize is default and smaller than the height of Config+Display and smaller than the (initial) height of Display2. Similar checks for Constraints / Margins. Other possiblity: Explicit Height's getting their grubby fingers in the mix.Stairs
On second thought: @GameCat's explanation is probably what is happening. If the order in the dfm does not reflect the order on screen, the splitter can end up where you do not expect it.Stairs
R
11

(Can't reproduce.) Splitters are tricky things. I always write code to position them. In this case, I would do

procedure Form1Show(Sender: TObject);
begin
  Splitter1.Top := DisplayArea2.Top;
end;
Rodneyrodolfo answered 11/3, 2011 at 18:41 Comment(3)
Choosing this rather than the Gamecat's solution because having explicit code in FormShow makes it less likely that someone poking the wrong thing in the form designer at a future point will do something that somehow breaks the fragile creation order that his solution relies on.Magnanimity
+1 this kind me stuff always works better in code than the designerShady
Smart move, you can shoot yourself in the foot quite easily while playing with the dfm files. But sometimes it is the easiest way to go.Transport
T
7

I have had similar problems in the past. They were cause by:

  1. controls that where made invisible.
  2. control creation order.

I think the splitter is created after config area and before display area1. If you create it after display area 1 it should be fine.

Transport answered 11/3, 2011 at 18:41 Comment(2)
+1. This might take away the need for custom positioning code.Rodneyrodolfo
+1 That is far more likely than what I wrote in the comments! Dfm order is not always (hardly ever) the same as the order on screen.Stairs
P
6

I also had the same problem in the past. TSplitter should be placed between two TPanel, like such:

+---------------------------------------------+
|+-------------------------------------------+|
||                                           ||
|| CONFIG AREA                               ||
|| Align: alTop                              ||
|+-------------------------------------------+|
||                                           ||
|| DISPLAY AREA 1                            ||
|| Align: alClient                           ||
|+-------------------------------------------+|
+---------------------------------------------+
=============================================== <-TSplitter Align: alTop
|                                             |
| DISPLAY AREA 2                              |
| align: alClient                             |
----------------------------------------------- <-bottom of dialog

Config Area and Display Area 1 should now be contained inside a TPanel with Align := alTop and either the Config Area or the Display Area 1 should be aligned to alClient.

Hope this helps

Pruritus answered 11/3, 2011 at 18:53 Comment(1)
Yes, this is also a good solution, but it might sometimes feel a bit "overkill".Rodneyrodolfo

© 2022 - 2024 — McMap. All rights reserved.