уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Компонент TRelativePanel появился в Delphi относительно недавно. TRelativePanel — это контейнерный элемент управления, который позволяет позиционировать дочерние элементы управления относительно самой панели или относительно других дочерних элементов управления этой панели.

Основная информация по компоненту
Вкладка палитры компонентов Windows 10
Исходник официального примера и документация SourceForge DocWiki

Демонстрационный пример показывает каким образом можно размещать различные контролы в TRelativePanel и выравнивать их относительно друг друга.

Приложение использует следующие элементы управления:

  • RelativePanel1: компонент TRelativePanel, на которой размещены:
    • Button1: кнопка управления.
    • Edit1: элемент управления редактирования.
    • Shape1: форма.
  • pageControl1: TPageControl с вкладками для каждого из элементов управления на панели TRelativePanel.
    • TabSheet1, TabSheet2, TabSheet3 (Edit1, Button1, Shape1): вкладки pageControl1. Каждый содержит флажки и раскрывающиеся меню, которые управляют свойствами соответствующего элемента управления на соответствующей панели.
      • cbAlignLeftWithPanel: переключает свойство AlignLeftWithPanel связанного элемента управления.
      • cbAlignHor horizontalCenterWithPanel: переключает свойство AlignHorizontalCenterWithPanel связанного элемента управления.
      • cbAlignRightWithPanel: переключает свойство AlignRightWithPanel связанного элемента управления.
      • cbAlignTopWithPanel: переключает свойство AlignTopWithPanel связанного элемента управления.
      • cbAlignVerticalCenterWithPanel: переключает свойство AlignVerticalCenterWithPanel связанного элемента управления.
      • cbAlignBottomWithPanel: переключает свойство AlignBottomWithPanel связанного элемента управления.
      • cbxLeftOf: позволяет изменить свойство LeftOf связанного элемента управления.
      • cbxAlignLeftWith: позволяет изменить свойство AlignLeftWith связанного элемента управления.
      • cbxAlignHorizontalCenterWith: Позволяет изменить свойство AlignHorizontalCenterWith связанного элемента управления.
      • cbxAlignRightWith: позволяет изменить свойство AlignRightWith связанного элемента управления.
      • cbxRightOf: позволяет изменить свойство RightOf связанного элемента управления.
      • cbxAbove: позволяет изменить свойство Above связанного элемента управления.
      • cbxAlignTopWith: позволяет изменить свойство AlignTopWith связанного элемента управления.
      • cbxAlignVerticalCenterWith: позволяет изменить свойство AlignVerticalCenterWith связанного элемента управления.
      • cbxAlignBottomWith: позволяет изменить свойство AlignBottomWith связанного элемента управления.
      • cbxBelow: позволяет изменить свойство Below связанного элемента управления.
      • cbxVclStyles: список, который позволяет вам изменить стиль приложения. Вы можете выбрать любой стиль, который активен в параметрах «Application Appearance — Custom Styles» для этого проекта.

Внешний вид демонстрационного приложения представлен на рисунке ниже:

Использование компонента TRelativePanel

Приоритет правил выравнивания

Процесс позиционирования дочерних элементов относительной панели выполняется в следующем порядке:

  1. AlignXxWithPanel: любые свойства «Align», связанные с «Panel», такие как AlignLeftWithPanel.
    • Центрирование (AlignXxCenterWithPanel) имеет приоритет над выравниванием по сторонам.
    • Выравнивание по левой стороне имеет приоритет над выравниванием по правой и сверху вниз.
  2. AlignXxWith: остальные свойства «Align».
    • Центрирование (AlignXxCenterWith) имеет приоритет над выравниванием по сторонам.
    • Выравнивание по левой стороне имеет приоритет над выравниванием по правой и сверху вниз.
  3. Выравнивание сторон: LeftOfRightOfAbove и Below.
    1. Выравнивание по левой стороне имеет приоритет над выравниванием по правой и сверху вниз.

Порядок расположения дочерних элементов в шагах 2 и 3 зависит от их индекса в массиве дочерних элементов (ControlCollection). Если вы хотите, чтобы один элемент управления «выиграл» перед другим в конфликте выравнивания, установите индекс элемента управления для выше (2 вместо 3, 1 вместо 2 и т.д.).

На что обратить особое внимание при работе с TRelativePanel?

Выравнивание вне поля зрения (исчезающие элементы управления)

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

Круговая зависимость элементов на панели

Связь между элементами внутри TRelativePanel формирует ориентированный граф. Круговая зависимость возникает, когда в этом графе есть цикл. То есть два элемента зависят друг от друга, в том числе через промежуточные элементы.

Когда вы устанавливаете циклическую зависимость, компонент TRelativePanel обнаруживает ее и выдает исключение.

Если это происходит во время разработки, то в дизайнере отображается сообщение об ошибке. Код, вызывающий элементы EnableAlign или Realign, также может вызвать исключение.

Конфликтующие отношения

Если вы установите несколько выравниваний, нацеленных на один и тот же край элемента управления, вы можете столкнуться с конфликтом. Прочитайте ещё раз раздел «Приоритет правил выравнивания» для получения дополнительной информации о том, какие правила выравнивания имеют приоритет над другими.

Выравнивание кромок и автоматическое изменение размеров

Если вы установили выравнивание противоположного края (левый и правый, верхний и нижний) элемента управления к одной и той же цели («Панель» или другой элемент управления), затронутый элемент управления автоматически изменит свою ширину или высоту в соответствии с шириной цели. Например, если для кнопки вы установите и AlignLeftWithPanel, и AlignRightWithPanel, эта кнопка изменит свою ширину в соответствии с шириной соответствующей панели.

Такое поведение может привести к неожиданным ситуациям. Например, если вы установите и AlignLeftWithPanel  и AlignRightWithPanel для TEdit, который должен быть слева от кнопки. Для элемента управления «кнопка» элемент управления принимает ширину относительной панели, но из-за правила положения кнопки «слева от» элемент управления выходит за пределы TRealtivePanel.

Демонстрационный пример

В зависимости от выбранных настроек, приложение демонстрирует изменение различных свойств компонента TRelativePanel и, соответственно, меняет положение размещенных на панели элементов.

В приложении использованы события Drag&Drop элементов, размещенных на панели TRelativePanel. Поэтому вы можете перетаскивать элементы управления по панели. Реализация событий Drag&Drop следующая:

procedure TRelativePanelForm.RelativePanel1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
  TControl(Source).Left := X - FStartDragPosOffset.X;
  TControl(Source).Top := Y - FStartDragPosOffset.Y;
end;
 
procedure TRelativePanelForm.RelativePanel1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState;
  var Accept: Boolean);
begin
  Accept := true;
end;

У элементов, размещенных на TRelativePanel также определены события OnClik. Срабатывание события приводит к активации соответствующего TabSheet у компонента TConrolPage. Обработчик события:

procedure TRelativePanelForm.SampleControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
begin
  if Button = mbLeft then
  begin
    TControl(Sender).BeginDrag(True);
    FStartDragPosOffset.SetLocation(X, Y);
 
    PageControl1.ActivePageIndex := TControl(Sender).Tag;
  end;
end;

Для работы с различными стилями оформления используются следующие методы:

procedure TRelativePanelForm.FormCreate(Sender: TObject);
var
  StyleName: string;
begin
  //заполнение TComboBax стилями, которые можно использовать
  for StyleName in TStyleManager.StyleNames do 
    cbxVclStyles.Items.Add(StyleName);
  //выбор в TComboBox активного стиля
  cbxVclStyles.ItemIndex := cbxVclStyles.Items.IndexOf(TStyleManager.ActiveStyle.Name);
end;
 
procedure TRelativePanelForm.cbxVclStylesChange(Sender: TObject);
begin
  //смена стиля оформления при выборе в TComboBox
  TStyleManager.SetStyle(cbxVclStyles.Text);
end;

На рисунке ниже представлен пример работающего демонстрационного приложения с выбранным стилем оформления и настройками расположения компонента TShape на панели TRelativePanel:

При подготовке статьи использовалась информация со следующих ресурсов:

  1. Официальный репозиторий демострационных примеров Delphi на SourceForge
  2. Документация по компоненту на сайте Embarcadero
  3. Информация по работе с компонентом TRealtivePanel на сайте Embarcadero

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.