Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep controls visible in the form when using a splitter?

On a form, I have two large controls and a TSplitter between them. The control on the top is aligned to the top and the control on the bottom is aligned to the client. So when I resize the form, the control on the top remains the same height while the one on the bottom varies. Then the splitter between them essentially controls the height of the control on the top.

However, when the form is resized to a smaller height than the top control, the bottom control becomes hidden. I've tried using the constraints to tweak how this reacts, but with no luck...

  • When the splitter is resized, it shouldn't allow the user to drag it down any further than the bottom control's min height
  • When the form is resized smaller than the bottom control allows, it should automatically resize the top control's height to allow the bottom control to fit
  • When I set the bottom control's MinHeight constraint to, for example, 100, when resizing the splitter, it makes the form actually grow to fit the bottom control, rather than stopping the user from sizing any further.
  • When I set the splitter's MinSize property to, for example, 100, when resizing the splitter, I get very abnormal results (top control disappearing) and still hides the bottom control.

How do I make sure the bottom control is always visible when splitter or form are resizing without altering the size of the form?

DFM Code:

object Form1: TForm1
  Left = 310
  Top = 121
  Caption = 'Form1'
  ClientHeight = 374
  ClientWidth = 434
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Splitter1: TSplitter
    Left = 0
    Top = 129
    Width = 434
    Height = 7
    Cursor = crVSplit
    Align = alTop
    Beveled = True
  end
  object Panel1: TPanel
    Left = 0
    Top = 0
    Width = 434
    Height = 129
    Align = alTop
    Caption = 'Panel1'
    TabOrder = 0
    ExplicitLeft = 48
    ExplicitTop = 16
    ExplicitWidth = 313
  end
  object Panel2: TPanel
    Left = 0
    Top = 136
    Width = 434
    Height = 238
    Align = alClient
    Caption = 'Panel2'
    TabOrder = 1
    ExplicitLeft = 16
    ExplicitTop = 168
    ExplicitWidth = 369
    ExplicitHeight = 145
  end
end
like image 837
Jerry Dodge Avatar asked Jul 01 '14 23:07

Jerry Dodge


1 Answers

When the splitter is resized, it shouldn't allow the user to drag it down any further than the bottom control's min height

Add a handler for OnCanResize of the splitter to prevent dragging it down further than a predefined height:

procedure TForm1.Splitter1CanResize(Sender: TObject; var NewSize: Integer;
  var Accept: Boolean);
begin
  Accept := NewSize <=
      ClientHeight - (100 + Splitter1.Height);
end;

(100 being the predefined height, replace them with a constant/property...)


When the form is resized smaller than the bottom control allows, it should automatically resize the top control's height to allow the bottom control to fit

First, you'd better have a constraint on the form to have all controls have positive heights at all times. Otherwise you're likely to struggle with an alignment race: panel1 and splitter1 being aligned on top:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Constraints.MinHeight := Height - ClientHeight + 100 + Splitter1.Height + 1;
end;

Second, you can check if form resize cause bottom panel to be resized smaller than it should be, and take corrective action:

procedure TForm1.FormResize(Sender: TObject);
begin
  if Panel2.Height < 100 then
    Panel1.Height := ClientHeight - (100 + Splitter1.Height);
end;


When I set the bottom control's MinHeight constraint to, for example, 100, when resizing the splitter, it makes the form actually grow to fit the bottom control, rather than stopping the user from sizing any further.

Do not use bottom panel's constraints.


When I set the splitter's MinSize property to, for example, 100, when resizing the splitter, I get very abnormal results (top control disappearing) and still hides the bottom control.

Do not use splitter's MinSize.

like image 178
Sertac Akyuz Avatar answered Nov 15 '22 03:11

Sertac Akyuz