Почему полосы прокрутки в пользовательском контроле, производном от TPresentedScrollbox, не отображаются?

Вопрос или проблема

Следующий код работает для создания TPresentedScrollBox во время выполнения и ручного показа полос прокрутки (установки пользовательского размера содержимого):

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.ScrollBox;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    FScrollBox: TPresentedScrollBox;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FScrollBox := TPresentedScrollBox.Create(nil);
  FScrollBox.Parent := Self; // эта строка, похоже, необходима для отображения полос прокрутки
  FScrollBox.Align := TAlignLayout.Client;
  FScrollBox.AutoCalculateContentSize := False;
  FScrollBox.ContentSize.Width := 1024;
  FScrollBox.ContentSize.Height := 1024;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FScrollBox.Free;
end;

end.

Однако, когда я пытаюсь сделать то же самое в пользовательском контроле, полосы прокрутки никогда не появляются:

unit Unit2;

interface

uses
  System.Classes,
  FMX.Types,
  FMX.ScrollBox;

type
  TFMXScrollBox = class(TPresentedScrollBox)
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

implementation

{ TFMXScrollBox }

constructor TFMXScrollBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  AutoCalculateContentSize := False;
  ContentSize.Width := 1024;
  ContentSize.Height := 1024;
end;

destructor TFMXScrollBox.Destroy;
begin
  inherited Destroy;
end;

end.

Создание экземпляра:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.ScrollBox, Unit2;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    FScrollBox: TFMXScrollBox;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FScrollBox := TFMXScrollBox.Create(nil);
  FScrollBox.Parent := Self;
  FScrollBox.Align := TAlignLayout.Client;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FScrollBox.Free;
end;

end.

Полосы прокрутки больше не появляются. Мне кажется, что это как-то связано с родительским элементом, так как в самом первом примере кода пропуск строки FScrollBox.Parent := Self; также предотвращает отображение полос прокрутки.

Есть идеи, что здесь происходит?

Ответ или решение

Причина, по которой полосы прокрутки не отображаются в кастомном контроле, производном от TPresentedScrollBox, связана с тем, как установлен размер содержимого и родителя контролла.

В вашем первом примере, когда вы создаете экземпляр TPresentedScrollBox, вы устанавливаете Parent для FScrollBox непосредственно в методе FormCreate, что позволяет компоненту корректно вычислить свои размеры и отобразить полосы прокрутки. По умолчанию, без установки родителя, TPresentedScrollBox не может корректно инициализировать свои свойства расположения и размеров, из-за чего полосы прокрутки не появляются.

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

Чтобы решить проблему, убедитесь, что вы устанавливаете Parent вашего кастомного компонента после его создания. Это можно сделать следующим образом:

  1. Убедитесь, что задаете нужные значения для размеров содержимого как в конструкторе компонента, так и после его создания во внешнем классе (в FormCreate).
  2. Необходимо также установить Align для FScrollBox, чтобы компонент занимал доступное пространство в родительском элементе.

Обновленный код будет выглядеть так:

procedure TForm1.FormCreate(Sender: TObject);
begin
  FScrollBox := TFMXScrollBox.Create(Self); // Здесь устанавливается Self как владелец
  FScrollBox.Parent := Self; // Установка родителя
  FScrollBox.Align := TAlignLayout.Client; // Установка поведения выравнивания
  FScrollBox.AutoCalculateContentSize := False; // Отключаем автоподсчет
  FScrollBox.ContentSize.Width := 1024; // Устанавливаем ширину содержимого
  FScrollBox.ContentSize.Height := 1024; // Устанавливаем высоту содержимого
end;

Таким образом, полосы прокрутки должны отображаться должным образом. Основное внимание следует уделить тому, как контрол высчитывает размеры и как это связано с поведением его родителя. Убедитесь, что в вашем кастомном контроле все нужные параметры и установки размера содержимого выполнены в нужное время в жизненном цикле приложения.

Оцените материал
Добавить комментарий

Капча загружается...