Как сохранить элементы управления видимыми в форме при использовании разделителя?

#delphi #resize #splitter

#delphi #изменение размера #разделитель

Вопрос:

В форме у меня есть два больших элемента управления и TSplitter между ними. Элемент управления сверху выровнен по верху, а элемент управления снизу выровнен по клиенту. Поэтому, когда я изменяю размер формы, элемент управления вверху остается той же высоты, в то время как элемент управления внизу меняется. Тогда разделитель между ними по существу контролирует высоту элемента управления сверху.

Однако, когда форма изменяется на меньшую высоту, чем верхний элемент управления, нижний элемент управления становится скрытым. Я пытался использовать ограничения, чтобы настроить, как это реагирует, но безуспешно…

  • Когда размер разделителя изменяется, он не должен позволять пользователю перетаскивать его вниз дальше минимальной высоты нижнего элемента управления
  • Когда размер формы меньше, чем позволяет нижний элемент управления, он должен автоматически изменять высоту верхнего элемента управления, чтобы позволить нижнему элементу управления поместиться
  • Когда я устанавливаю MinHeight ограничение для нижнего элемента управления, например, на 100, при изменении размера разделителя форма фактически увеличивается, чтобы соответствовать нижнему элементу управления, а не мешает пользователю изменять размер дальше.
  • Когда я устанавливаю для MinSize свойства разделителя значение, например, 100, при изменении размера разделителя я получаю очень ненормальные результаты (верхний элемент управления исчезает) и по-прежнему скрывает нижний элемент управления.

Как мне убедиться, что нижний элемент управления всегда виден при изменении размера разделителя или формы, не изменяя размер формы?

Код DFM:

 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
  

Ответ №1:

Когда размер разделителя изменяется, он не должен позволять пользователю перетаскивать его вниз дальше минимальной высоты нижнего элемента управления

Добавьте обработчик для OnCanResize разделителя, чтобы предотвратить перетаскивание его вниз дальше предопределенной высоты:

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

(100 — это предопределенная высота, замените их константой / свойством …)

Когда размер формы меньше, чем позволяет нижний элемент управления, он должен автоматически изменять высоту верхнего элемента управления, чтобы позволить нижнему элементу управления поместиться

Во-первых, вам лучше установить ограничение на форму, чтобы все элементы управления всегда имели положительную высоту. В противном случае вы, вероятно, столкнетесь с гонкой выравнивания: panel1 и splitter1 будут выровнены сверху:

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

Во-вторых, вы можете проверить, не приводит ли изменение размера формы к уменьшению размера нижней панели меньше, чем должно быть, и предпринять корректирующие действия:

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

Когда я устанавливаю ограничение minHeight для нижнего элемента управления, например, на 100, при изменении размера разделителя форма фактически увеличивается, чтобы соответствовать нижнему элементу управления, а не мешает пользователю изменять размер дальше.

Не используйте ограничения нижней панели.

Когда я устанавливаю для свойства minSize разделителя значение, например, 100, при изменении размера разделителя я получаю очень ненормальные результаты (верхний элемент управления исчезает) и по-прежнему скрывает нижний элемент управления.

Не используйте разделители MinSize .

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

1. Отлично работает 🙂 С добавлением удвоения ограничений по высоте формы, чтобы верхний элемент управления тоже отображался.