Панель управления.Автоматическое изменение размера не работает с вложенными панелями в специальной конфигурации

#delphi #autosize #delphi-10.4-sydney #tpanel

Вопрос:

В приложении Delphi 10.4.2 win-32 VCL в Windows 10 я использую несколько вложенных TPanel :

Вставьте эти элементы управления в пустую форму:

 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
 

Затем запустите скомпилированное приложение, и вы получите что — то вроде этого:

введите описание изображения здесь

Вы можете видеть, что панель pnlBackSide не имеет автоматического размера, хотя для ее свойства AutoSize установлено значение True . Почему?

Как сделать панель pnlBackSide автоматического размера?

Комментарии:

1. pnlFront имеет и Align = alClient то и AutoSize = True другое . Первый гласит: «Пожалуйста, используйте все пространство вашего родителя, то есть будьте как можно больше». В последнем говорится: «Пожалуйста, занимайте не больше места, чем требуется вашим детям, то есть будьте как можно меньше». Бедный Delphi VCL не может удовлетворить оба ваших желания одновременно.

2. Это правда, что оба желания являются ЛОГИЧЕСКОЙ ДИЛЕММОЙ и не могут быть выполнены одновременно. Может быть, лучше выполнять их последовательно?

Ответ №1:

Как правильно заметил Андреас, свойства pnlFront.Align = alClient и pnlFront.AutoSize = True являются ЛОГИЧЕСКОЙ ДИЛЕММОЙ (поскольку они КОНФЛИКТУЮТ) и, следовательно, не могут быть выполнены одновременно. Таким образом, решение состоит в том, чтобы выполнить их последовательно, установив их на pnlFront.Align = alNone и pnlFront.AutoSize = False во время разработки. А затем во время выполнения выполняйте их последовательно:

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

Кроме того, для компенсации pnlComboBack.Margins.Bottom также pnlBackSide.AutoSize необходимо установить значение False во время разработки , а затем True во время выполнения (в правильном порядке):

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

Так что результат теперь идеальный:

введите описание изображения здесь