delphiautosizedelphi-10.4-sydneytpanel

TPanel.AutoSize does not work with nested panels in a special configuration


In a Delphi 10.4.2 win-32 VCL Application in Windows 10, I use several nested TPanel:

Paste these controls on an empty form:

object Panel1: TPanel
  Left = 0
  Top = 0
  Width = 494
  Height = 299
  Align = alClient
  BevelOuter = bvNone
  TabOrder = 0
  ExplicitLeft = 40
  ExplicitTop = 140
  ExplicitWidth = 185
  ExplicitHeight = 41
  object Splitter1: TSplitter
    Left = 222
    Top = 0
    Height = 299
    Align = alRight
    Color = clSilver
    ParentColor = False
    ExplicitLeft = 280
    ExplicitTop = 112
    ExplicitHeight = 100
  end
  object CardPanel1: TCardPanel
    Left = 225
    Top = 0
    Width = 269
    Height = 299
    Align = alRight
    ActiveCard = Card1
    BevelOuter = bvNone
    Caption = 'CardPanel1'
    Ctl3D = False
    ParentCtl3D = False
    TabOrder = 0
    ExplicitLeft = 272
    ExplicitHeight = 282
    object Card1: TCard
      Left = 0
      Top = 0
      Width = 269
      Height = 299
      Caption = 'Card1'
      CardIndex = 0
      TabOrder = 0
      ExplicitLeft = 1
      ExplicitTop = 1
      ExplicitWidth = 298
      ExplicitHeight = 280
      object pnlBackSide: TPanel
        AlignWithMargins = True
        Left = 10
        Top = 10
        Width = 249
        Height = 263
        Margins.Left = 10
        Margins.Top = 10
        Margins.Right = 10
        Margins.Bottom = 0
        Align = alTop
        AutoSize = True
        Color = clBlue
        ParentBackground = False
        TabOrder = 0
        object pnlFront: TPanel
          AlignWithMargins = True
          Left = 2
          Top = 2
          Width = 245
          Height = 259
          Margins.Left = 1
          Margins.Top = 1
          Margins.Right = 1
          Margins.Bottom = 1
          Align = alClient
          AutoSize = True
          BevelOuter = bvNone
          ParentBackground = False
          TabOrder = 0
          ExplicitWidth = 274
          ExplicitHeight = 243
          object lblBlaBla: TLabel
            AlignWithMargins = True
            Left = 3
            Top = 3
            Width = 239
            Height = 13
            Align = alTop
            Alignment = taCenter
            Caption = 'BLA BLA'
            ExplicitWidth = 39
          end
          object listboxTest: TListBox
            AlignWithMargins = True
            Left = 10
            Top = 19
            Width = 225
            Height = 55
            Margins.Left = 10
            Margins.Right = 10
            Margins.Bottom = 0
            Align = alTop
            BevelInner = bvNone
            ItemHeight = 13
            TabOrder = 0
            ExplicitWidth = 254
          end
          object Button1: TButton
            AlignWithMargins = True
            Left = 10
            Top = 78
            Width = 225
            Height = 25
            Margins.Left = 10
            Margins.Top = 4
            Margins.Right = 10
            Margins.Bottom = 0
            Align = alTop
            Caption = 'Button1'
            TabOrder = 1
            ExplicitWidth = 254
          end
          object Button3: TButton
            AlignWithMargins = True
            Left = 10
            Top = 136
            Width = 225
            Height = 25
            Margins.Left = 10
            Margins.Top = 4
            Margins.Right = 10
            Margins.Bottom = 0
            Align = alTop
            Caption = 'Button3'
            TabOrder = 2
            ExplicitWidth = 254
          end
          object Button4: TButton
            AlignWithMargins = True
            Left = 10
            Top = 165
            Width = 225
            Height = 25
            Margins.Left = 10
            Margins.Top = 4
            Margins.Right = 10
            Margins.Bottom = 0
            Align = alTop
            Caption = 'Button4'
            TabOrder = 3
            ExplicitWidth = 254
          end
          object Button2: TButton
            AlignWithMargins = True
            Left = 10
            Top = 107
            Width = 225
            Height = 25
            Margins.Left = 10
            Margins.Top = 4
            Margins.Right = 10
            Margins.Bottom = 0
            Align = alTop
            Caption = 'Button2'
            TabOrder = 4
            ExplicitWidth = 254
          end
          object pnlComboBack: TPanel
            AlignWithMargins = True
            Left = 10
            Top = 194
            Width = 225
            Height = 21
            Margins.Left = 10
            Margins.Top = 4
            Margins.Right = 10
            Margins.Bottom = 4
            Align = alTop
            AutoSize = True
            BevelOuter = bvNone
            TabOrder = 5
            ExplicitWidth = 254
            object cbbTest: TComboBox
              Left = 0
              Top = 0
              Width = 225
              Height = 21
              Margins.Left = 10
              Margins.Top = 4
              Margins.Right = 10
              Margins.Bottom = 4
              Align = alClient
              Style = csDropDownList
              ItemIndex = 0
              TabOrder = 0
              Text = 'Select an item'
              Items.Strings = (
                'Select an item')
              ExplicitWidth = 254
            end
          end
        end
      end
    end
  end
end

Then run the compiled app und you get something like this:

enter image description here

You can see that the panel pnlBackSide does not auto-size although its property AutoSize is set to True. Why?

How to make the panel pnlBackSide auto-size?


Solution

  • As Andreas correctly observed, the properties pnlFront.Align = alClient and pnlFront.AutoSize = True are a LOGICAL DILEMMA (as they are CONFLICTING) and thus cannot be executed at the same time. So the solution is to execute them consecutively by setting them to pnlFront.Align = alNone and pnlFront.AutoSize = False at design-time. And then at run-time, execute them consecutively:

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      pnlFront.AutoSize := True;
      pnlFront.Align := alClient;
    end;
    

    Also, to compensate for pnlComboBack.Margins.Bottom, also pnlBackSide.AutoSize must be set to False at design-time, and then to True at run-time (in the correct order):

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      pnlFront.AutoSize := True;
      pnlBackSide.AutoSize := True;
      pnlFront.Align := alClient;
    end;
    

    So the result is now perfect:

    enter image description here