Вопрос или проблема
Следующий код работает для создания 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
вашего кастомного компонента после его создания. Это можно сделать следующим образом:
- Убедитесь, что задаете нужные значения для размеров содержимого как в конструкторе компонента, так и после его создания во внешнем классе (в
FormCreate
). - Необходимо также установить
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;
Таким образом, полосы прокрутки должны отображаться должным образом. Основное внимание следует уделить тому, как контрол высчитывает размеры и как это связано с поведением его родителя. Убедитесь, что в вашем кастомном контроле все нужные параметры и установки размера содержимого выполнены в нужное время в жизненном цикле приложения.