Included is a small project demonstrating my problem. I have a TPageControl
aligned to the main form. On each of two tabsheets I have panels client aligned. On each of those panels I have 2 subpanels and a splitter. The LH panel and splitter is aligned left, the RH panel client-aligned.
Basically the problem is interaction between the 2 tabs. To demonstrate:
- run the program
- stretch the main form horizontally. Panel 3 will grow
- move the splitter as far to the right as it will go. Panel 2 will grow, Panel 3 will shrink to its 10-pixel min-width constraint.
- select tabsheet 2. Panel 5 is as designed, panel 6 grew when the main form was stretched
- reduce the main form width to its original width. Panel 6 shrinks too much (undesirable)
- click on tabsheet 1. Main form increases in width again (undesirable)
OK, the behaviour is probably explainable in terms of the rules of aligned panels, but can anybody suggest improvements to the operation?
unit Unit17;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, ComCtrls;
type
TForm17 = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
Panel1: TPanel;
Panel2: TPanel;
Splitter1: TSplitter;
Panel3: TPanel;
Panel4: TPanel;
Splitter2: TSplitter;
Panel5: TPanel;
Panel6: TPanel;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form17: TForm17;
implementation
{$R *.dfm}
end.
object Form17: TForm17
Left = 0
Top = 0
Caption = 'Form17'
ClientHeight = 254
ClientWidth = 314
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object PageControl1: TPageControl
Left = 0
Top = 0
Width = 314
Height = 254
ActivePage = TabSheet1
Align = alClient
Constraints.MinWidth = 30
TabOrder = 0
ExplicitWidth = 480
object TabSheet1: TTabSheet
Caption = 'TabSheet1'
ExplicitWidth = 281
ExplicitHeight = 165
object Panel1: TPanel
Left = 0
Top = 0
Width = 306
Height = 226
Align = alClient
Caption = 'Panel1'
TabOrder = 0
ExplicitWidth = 109
ExplicitHeight = 165
object Splitter1: TSplitter
Left = 151
Top = 1
Width = 12
Height = 224
ExplicitLeft = 145
end
object Panel2: TPanel
Left = 1
Top = 1
Width = 150
Height = 224
Align = alLeft
Caption = 'Panel2'
Constraints.MinWidth = 10
TabOrder = 0
end
object Panel3: TPanel
Left = 163
Top = 1
Width = 142
Height = 224
Align = alClient
Caption = 'Panel3'
Constraints.MinWidth = 10
TabOrder = 1
ExplicitLeft = 141
ExplicitWidth = 330
end
end
end
object TabSheet2: TTabSheet
Caption = 'TabSheet2'
ImageIndex = 1
ExplicitWidth = 281
ExplicitHeight = 165
object Panel4: TPanel
Left = 0
Top = 0
Width = 306
Height = 226
Align = alClient
Caption = 'Panel4'
TabOrder = 0
ExplicitWidth = 109
ExplicitHeight = 165
object Splitter2: TSplitter
Left = 149
Top = 1
Width = 11
Height = 224
ExplicitLeft = 141
end
object Panel5: TPanel
Left = 1
Top = 1
Width = 148
Height = 224
Align = alLeft
Caption = 'Panel5'
Constraints.MinWidth = 10
TabOrder = 0
end
object Panel6: TPanel
Left = 160
Top = 1
Width = 145
Height = 224
Align = alClient
Caption = 'Panel6'
Constraints.MinWidth = 10
TabOrder = 1
ExplicitLeft = 141
ExplicitWidth = 139
ExplicitHeight = 163
end
end
end
end
end
If while the form was wider you moved the splitter far to the right then reduced the form's width so it became narrower than the left-hand panel (and thus the splitter found itself 'outside' the form), what should the behaviour of your form be in this case? You have been asked about your criteria for desirable behaviour and all I can see in your answer so far is your understanding of undesirable behaviour.
Now I have been concerned a couple of times with possible side effects of resizing a form that has panels and splitters on it. I didn't investigate very much into it and so in particular I never knew before about the auto-resize effect like in your situations. Anyway, in order to prevent most (if not any) of the possible behavioral artefacts I considered using
TScrollBox
as a parent control to panels and splitters instead ofTPanel
.I believe, this would change resizing of the form into resizing of the scroll box's client area, which would work fine for me in however few little projects of mine where I used splitters, if I employed tabsheets like you do. However I cannot know about your case. And I understand that this is more of a workaround than a solution to your problem.
Not necessarily a real answer, but a couple of remarks:
MinSize voor an alLeft aligned Splitter pertains to the control on the Splitter's left and right. Your Panel 6 is indeed resized to (slightly more than) its own minWidth (10) instead of the splitter's MinSize (30). You can more easily demonstrate this by adding two left aligned panels on each of your panels 2, 3, 5 and 6 and give them a width of 10 and 20 and a different color.
Selecting tabsheet one again after reducing the mainform's width, does grow the mainform (yikes) AND shows that now Panel3 has now also been reduced to its min width instead of the splitter's minSize.
The solution to the main form resizing? Dunno, but making sure your panels' minwidth is in sync with the splitters' minsize should remove the shrinking. And as Sertac says, I suspect that you simply need to opt for one or the other, but not both...
Update:
Setting the splitters' minSize to 30 and setting the panels' minWidth to 0. Takes away the mainform's resize, but does reduce the right hand panels to 0 width.
Setting the splitters' minSize to 30 and setting the panels' minWidth to 30, takes away the minimum width problems, but still resized the main form.
Setting the panels' minWidth to 30 and setting the splitters' minSize to 1 (the minimum) allows you to move the splitter all the way to the right and resizes the main form by the panels minWidth when you release the splitter. It does keep Panel6 from reducing to less than 30, but again the mainform resizes when you reselect tab 1.
It would seem that your best bet is to rely on the splitters' minSize and "manually" prevent the right hand panels from reducing to far by restricting the splitters' movement when it gets to far right. You can do this in the OnCanResize event of the splitters.
btw, using D2009
To get expected behavior remove the constraints (
MinWidth
) from your panels. These settings are currently ineffective anyway, since your splitters have aMinSize
of '30' (the default, not stored).edit (response to the comment): You cannot expect the 'MinWidth' constraint of a control that's at the right side of a splitter to adjust the size of the left-side control. That's only logical, the constraint is a property for the control that you set. All you'll achieve is that the form will deny shrinking if your control is already at its 'MinWidth', hence the undesirable behavior that you observe that the form is getting larger when you switch tabs. What you desire, you have to do with code - as Marjan told in his answer. There should be more than one way to achieve this, for instance, put the below to the Panel3's 'OnCanResize' event: