How to control the visual controls arrangement at runtime?

  

I have 2 TLayout controls with some controls inside (TLabel, TGridLayout, & TListView). I initially set both TLayout.Visibility to False at design time.

During runtime, and with same trigger, both TLayout.Visibility will change to True at the same time. The screenshot below will show you the visual error:

As you can see, the “variant” layout is overlapping the “size” layout.

Moreover, the “variant” layout should suppose to be precedent over the “size” layout.

Heres the exact arrangement I did at design-time, and it should appear in this manner:

I realized that the arrangement I did at design-time is not guaranteed to appear that way during runtime, especially in my case.

By the way, my 2 TLayout controls are inside a TVertScrollBox.

How do I control the arrangement of my visual controls at runtime?

.FMX file

object formMain: TformMain
Left = 0
Top = 0
Caption = ‘Project X Client’
ClientHeight = 596
ClientWidth = 405
StyleBook = stb1
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnCreate = FormCreate
OnKeyUp = FormKeyUp
DesignerMasterStyle = 0
object tabFooter: TTabControl
Touch.GestureManager = GestureManager1
OnGesture = GestureDone
Align = Client
FullSize = True
Size.Width = 405.000000000000000000
Size.Height = 596.000000000000000000
Size.PlatformDefault = False
TabHeight = 49.000000000000000000
TabIndex = 0
TabOrder = 0
TabPosition = Bottom
Sizes = (
405s
547s
405s
547s
405s
547s
405s
547s)
object tbiHome: TTabItem
CustomIcon = <
item
end>
IsSelected = True
Size.Width = 100.000000000000000000
Size.Height = 49.000000000000000000
Size.PlatformDefault = False
StyleLookup = ‘tabitemfavorites’
TabOrder = 0
Text = #144’Home’
ExplicitSize.cx = 101.000000000000000000
ExplicitSize.cy = 49.000000000000000000
object tabHome: TTabControl
Touch.GestureManager = GestureManager1
OnGesture = GestureDone
Align = Client
FullSize = True
Size.Width = 405.000000000000000000
Size.Height = 547.000000000000000000
Size.PlatformDefault = False
TabHeight = 49.000000000000000000
TabIndex = 2
TabOrder = 0
TabPosition = None
Sizes = (
405s
547s
405s
547s
405s
547s)

object tbiItemProfile: TTabItem
CustomIcon = <
item
end>
IsSelected = True
Size.Width = 8.000000000000000000
Size.Height = 8.000000000000000000
Size.PlatformDefault = False
StyleLookup = ”
TabOrder = 0
Text = #144
ExplicitSize.cx = 8.000000000000000000
ExplicitSize.cy = 8.000000000000000000
object vsbItemProfile: TVertScrollBox
Align = Client
Size.Width = 405.000000000000000000
Size.Height = 503.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
Viewport.Width = 389.000000000000000000
Viewport.Height = 503.000000000000000000
object glpItemPhoto: TGlyph
Margins.Left = 30.000000000000000000
Margins.Top = 20.000000000000000000
Margins.Right = 30.000000000000000000
Margins.Bottom = 10.000000000000000000
Align = Top
Position.X = 30.000000000000000000
Position.Y = 20.000000000000000000
Size.Width = 329.000000000000000000
Size.Height = 329.000000000000000000
Size.PlatformDefault = False
ImageIndex = 0
Images = imlImages
end
object lblItemBrand: TLabel
Align = Top
StyledSettings = [Family, FontColor]
Margins.Left = 37.000000000000000000
Margins.Top = 7.500000000000000000
Margins.Right = 37.000000000000000000
Margins.Bottom = 2.500000000000000000
Position.X = 37.000000000000000000
Position.Y = 366.500000000000000000
Size.Width = 315.000000000000000000
Size.Height = 16.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.StyleExt = {00070000000000000004000000}
TabOrder = 1
end
object lblItemDesc: TLabel
Align = Top
AutoSize = True
StyledSettings = [Family, Style, FontColor]
Margins.Left = 37.000000000000000000
Margins.Top = 2.500000000000000000
Margins.Right = 37.000000000000000000
Margins.Bottom = 7.500000000000000000
Position.X = 37.000000000000000000
Position.Y = 387.500000000000000000
Size.Width = 315.000000000000000000
Size.Height = 15.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 11.000000000000000000
TabOrder = 2
end
object spdAddToCart: TSpeedButton
Align = Top
StyledSettings = [Family, Size, FontColor]
Margins.Left = 120.000000000000000000
Margins.Top = 20.000000000000000000
Margins.Right = 120.000000000000000000
Margins.Bottom = 10.000000000000000000
Position.X = 120.000000000000000000
Position.Y = 668.500000000000000000
Size.Width = 149.000000000000000000
Size.Height = 44.000000000000000000
Size.PlatformDefault = False
StyleLookup = ‘speedbuttonstyle’
Text = ‘Add to Cart’
end
object lytBottomBuffer: TLayout
Align = Top
Position.Y = 722.500000000000000000
Size.Width = 389.000000000000000000
Size.Height = 20.000000000000000000
Size.PlatformDefault = False
TabOrder = 4
end
object lytSize: TLayout
Align = Top
Margins.Left = 37.000000000000000000
Margins.Top = 10.000000000000000000
Margins.Right = 37.000000000000000000
Position.X = 37.000000000000000000
Position.Y = 530.500000000000000000
Size.Width = 315.000000000000000000
Size.Height = 118.000000000000000000
Size.PlatformDefault = False
TabOrder = 5
object recSize: TRectangle
Align = Top
Size.Width = 315.000000000000000000
Size.Height = 18.000000000000000000
Size.PlatformDefault = False
Stroke.Kind = None
object lblSize: TLabel
Align = Top
StyledSettings = [Family, Style, FontColor]
Margins.Left = 2.000000000000000000
Position.X = 2.000000000000000000
Size.Width = 313.000000000000000000
Size.Height = 18.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 11.000000000000000000
Text = ‘Please choose the size:’
TabOrder = 0
end
end
object gdlSize: TGridLayout
Align = Top
ItemHeight = 100.000000000000000000
ItemWidth = 157.500000000000000000
Orientation = Horizontal
Position.Y = 18.000000000000000000
Size.Width = 315.000000000000000000
Size.Height = 100.000000000000000000
Size.PlatformDefault = False
TabOrder = 1
object lsvContainer: TListView
ItemAppearanceClassName = ‘TListItemAppearance’
ItemEditAppearanceClassName = ‘TListItemShowCheckAppearance’
HeaderAppearanceClassName = ‘TListHeaderObjects’
FooterAppearanceClassName = ‘TListHeaderObjects’
Transparent = True
Align = Contents
Size.Width = 157.500000000000000000
Size.Height = 100.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
ItemAppearance.ItemHeight = 25
ItemAppearanceObjects.ItemObjects.Text.Font.Size = 11.000000000000000000
ItemAppearanceObjects.ItemObjects.Text.WordWrap = True
ItemAppearanceObjects.ItemObjects.Text.Width = 75.000000000000000000
ItemAppearanceObjects.ItemObjects.Text.Height = 25.000000000000000000
ItemAppearanceObjects.ItemObjects.Accessory.Width = 10.000000000000000000
CanSwipeDelete = False
OnItemClick = lsvContainerItemClick
end
object lsvSize: TListView
ItemAppearanceClassName = ‘TListItemAppearance’
ItemEditAppearanceClassName = ‘TListItemShowCheckAppearance’
HeaderAppearanceClassName = ‘TListHeaderObjects’
FooterAppearanceClassName = ‘TListHeaderObjects’
Transparent = True
Align = Contents
Size.Width = 157.500000000000000000
Size.Height = 100.000000000000000000
Size.PlatformDefault = False
TabOrder = 1
ItemAppearance.ItemHeight = 25
ItemAppearanceObjects.ItemObjects.Text.Font.Size = 11.000000000000000000
ItemAppearanceObjects.ItemObjects.Text.Width = 84.000000000000000000
ItemAppearanceObjects.ItemObjects.Text.Height = 25.000000000000000000
ItemAppearanceObjects.ItemObjects.Accessory.Width = 10.000000000000000000
ItemAppearanceObjects.ItemObjects.Accessory.Visible = False
CanSwipeDelete = False
end
end
end
object lytVariant: TLayout
Align = Top
Margins.Left = 37.000000000000000000
Margins.Top = 10.000000000000000000
Margins.Right = 37.000000000000000000
Margins.Bottom = 7.500000000000000000
Position.X = 37.000000000000000000
Position.Y = 420.000000000000000000
Size.Width = 315.000000000000000000
Size.Height = 93.000000000000000000
Size.PlatformDefault = False
TabOrder = 6
object recVariant: TRectangle
Align = Top
Size.Width = 315.000000000000000000
Size.Height = 18.000000000000000000
Size.PlatformDefault = False
Stroke.Kind = None
object lblVariant: TLabel
Align = Top
StyledSettings = [Family, Style, FontColor]
Margins.Left = 2.000000000000000000
Position.X = 2.000000000000000000
Size.Width = 313.000000000000000000
Size.Height = 18.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 11.000000000000000000
Text = ‘Please choose the variant:’
TabOrder = 0
end
end
object lsvVariant: TListView
ItemAppearanceClassName = ‘TListItemAppearance’
ItemEditAppearanceClassName = ‘TListItemShowCheckAppearance’
HeaderAppearanceClassName = ‘TListHeaderObjects’
FooterAppearanceClassName = ‘TListHeaderObjects’
Transparent = True
ItemIndex = 0
Align = Top
Position.Y = 18.000000000000000000
Size.Width = 315.000000000000000000
Size.Height = 80.000000000000000000
Size.PlatformDefault = False
TabOrder = 1
ItemAppearance.ItemHeight = 25
ItemAppearanceObjects.ItemObjects.Text.Font.Size = 11.000000000000000000
ItemAppearanceObjects.ItemObjects.Text.WordWrap = True
ItemAppearanceObjects.ItemObjects.Text.Trimming = None
ItemAppearanceObjects.ItemObjects.Text.Width = 290.000000000000000000
ItemAppearanceObjects.ItemObjects.Text.Height = 25.000000000000000000
ItemAppearanceObjects.ItemObjects.Accessory.Width = 10.000000000000000000
ItemAppearanceObjects.ItemObjects.Accessory.Visible = False
CanSwipeDelete = False
end
end
end
object tlbItemCat: TToolBar
Size.Width = 405.000000000000000000
Size.Height = 44.000000000000000000
Size.PlatformDefault = False
TabOrder = 1
object lblItemCat: TLabel
Align = Contents
StyledSettings = [Family, FontColor]
Size.Width = 405.000000000000000000
Size.Height = 44.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 18.000000000000000000
TextSettings.HorzAlign = Center
TabOrder = 0
end
object spdBackProfile: TSpeedButton
Action = PreviousTabAction1
Align = Left
Enabled = True
ImageIndex = -1
Size.Width = 44.000000000000000000
Size.Height = 44.000000000000000000
Size.PlatformDefault = False
StyleLookup = ‘arrowlefttoolbutton’
end
end
end
end
end
object tbiCart: TTabItem
CustomIcon = <
item
end>
IsSelected = False
Size.Width = 100.000000000000000000
Size.Height = 49.000000000000000000
Size.PlatformDefault = False
StyleLookup = ‘tabitemcontacts’
TabOrder = 0
Text = ‘Cart’
ExplicitSize.cx = 102.000000000000000000
ExplicitSize.cy = 49.000000000000000000
object ToolBar3: TToolBar
Size.Width = 405.000000000000000000
Size.Height = 44.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
object lblTitle3: TLabel
Align = Contents
Size.Width = 405.000000000000000000
Size.Height = 44.000000000000000000
Size.PlatformDefault = False
StyleLookup = ‘toollabel’
TextSettings.HorzAlign = Center
Text = ‘Title’
end
end
end
object tbiTracker: TTabItem
CustomIcon = <
item
end>
IsSelected = False
Size.Width = 100.000000000000000000
Size.Height = 49.000000000000000000
Size.PlatformDefault = False
StyleLookup = ‘tabitemsearch’
TabOrder = 0
Text = ‘Tracker’
ExplicitSize.cx = 101.000000000000000000
ExplicitSize.cy = 49.000000000000000000
object ToolBar4: TToolBar
Size.Width = 405.000000000000000000
Size.Height = 44.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
object lblTitle4: TLabel
Align = Contents
Size.Width = 405.000000000000000000
Size.Height = 44.000000000000000000
Size.PlatformDefault = False
StyleLookup = ‘toollabel’
TextSettings.HorzAlign = Center
Text = ‘Title’
end
end
end
object tbiChat: TTabItem
CustomIcon = <
item
end>
IsSelected = False
Size.Width = 103.000000000000000000
Size.Height = 49.000000000000000000
Size.PlatformDefault = False
StyleLookup = ‘tabitembookmarks’
TabOrder = 0
Text = ‘Chat’
ExplicitSize.cx = 99.000000000000000000
ExplicitSize.cy = 49.000000000000000000
end
end
object stb1: TStyleBook
Styles = <
item
end
item
Platform = ‘AndroidL Light’
end>
Left = 176
Top = 65528
end
object GestureManager1: TGestureManager
Sensitivity = 80.000000000000000000
Left = 48
Top = 209
GestureData = <
item
Control = tabFooter
Collection = <
item
GestureID = sgiLeft
end
item
GestureID = sgiRight
end>
end
item
Control = tabHome
Collection = <
item
GestureID = sgiLeft
end
item
GestureID = sgiRight
end>
end>
end
object ActionList1: TActionList
Left = 48
Top = 136
object NextTabAction1: TNextTabAction
Category = ‘Tab’
TabControl = tabHome
end
object PreviousTabAction1: TPreviousTabAction
Category = ‘Tab’
TabControl = tabHome
end
end
object bdrContainer: TBindSourceDB
DataSet = dmMain.qryContainer
ScopeMappings = <>
Left = 192
Top = 288
end
object bdrSize: TBindSourceDB
DataSet = dmMain.qrySize
ScopeMappings = <>
Left = 200
Top = 296
end
object bdlHome: TBindingsList
Methods = <>
OutputConverters = <>
Left = 116
Top = 5
object lcfVariant: TLinkListControlToField
Category = ‘Quick Bindings’
DataSource = bdrOther
FieldName = ‘variant’
Control = lsvVariant
FillExpressions = <>
FillHeaderExpressions = <>
FillBreakGroups = <>
end
object lcfContainer: TLinkListControlToField
Category = ‘Quick Bindings’
DataSource = bdrContainer
FieldName = ‘container’
Control = lsvContainer
FillExpressions = <>
FillHeaderExpressions = <>
FillBreakGroups = <>
end
object lcfSize: TLinkListControlToField
Category = ‘Quick Bindings’
DataSource = bdrSize
FieldName = ‘size’
Control = lsvSize
FillExpressions = <>
FillHeaderExpressions = <>
FillBreakGroups = <>
end
object lcfMeta: TLinkListControlToField
Category = ‘Quick Bindings’
DataSource = bdrMeta
FieldName = ‘meta’
Control = lsvMeta
FillExpressions = <>
FillHeaderExpressions = <>
FillBreakGroups = <>
end
object lcfItems: TLinkListControlToField
Category = ‘Quick Bindings’
DataSource = bdrItem
FieldName = ‘name’
Control = lsvSearches
FillExpressions = <
item
SourceMemberName = ‘description’
ControlMemberName = ‘Detail’
end>
FillHeaderExpressions = <>
FillHeaderFieldName = ‘category’
FillBreakGroups = <>
end
object lpfItemCat: TLinkPropertyToField
Category = ‘Quick Bindings’
DataSource = bdrItem
FieldName = ‘category’
Component = lblItemCat
ComponentProperty = ‘Text’
end
object lpfItemBrand: TLinkPropertyToField
Category = ‘Quick Bindings’
DataSource = bdrItem
FieldName = ‘name’
Component = lblItemBrand
ComponentProperty = ‘Text’
end
object lpfItemDesc: TLinkPropertyToField
Category = ‘Quick Bindings’
DataSource = bdrItem
FieldName = ‘description’
Component = lblItemDesc
ComponentProperty = ‘Text’
end
end
object bdrItem: TBindSourceDB
DataSet = dmMain.qryItems
ScopeMappings = <>
Left = 208
Top = 304
end
object bdrOther: TBindSourceDB
DataSet = dmMain.qryVariant
ScopeMappings = <>
Left = 216
Top = 312
end
object bdrItems: TBindSourceDB
DataSet = dmMain.qryVariants
ScopeMappings = <>
Left = 224
Top = 320
end
object bdrMeta: TBindSourceDB
DataSet = dmMain.qryMeta
ScopeMappings = <>
Left = 232
Top = 328
end
end

FMX Procedures

implementation

uses
dmMain_u, FireDAC.Stan.Param;

{$R *.fmx}

procedure TformMain.lsvContainerItemClick(const Sender: TObject;
const AItem: TListViewItem);
begin
//resizing the size gridlayout according to height container and size items
with dmMain_u.dmMain do
begin
if (qryContainer.RecordCount >= 0) or (qrySize.RecordCount >= 0) then
begin
lytSize.Visible := False;
lytSize.Visible := True;
spdAddToCart.Visible := True;
spdAddToCart.Visible := False;
lytBottomBuffer.Visible := True;
lytBottomBuffer.Visible := False;
vsbItemProfile.Visible := False;
vsbItemProfile.Visible := True;
if ((qryContainer.RecordCount * 25) + 18) >
((qrySize.RecordCount * 25) + 18) then
begin
lytSize.Height := (qryContainer.RecordCount * 25) + 18;
end
else if ((qryContainer.RecordCount * 25) + 18) <
((qrySize.RecordCount * 25) + 18) then
begin
lytSize.Height := (qrySize.RecordCount * 25) + 18;
end
else if (((qryContainer.RecordCount * 25) + 18) =
((qrySize.RecordCount * 25) + 18)) then
begin
lytSize.Height := (qryContainer.RecordCount * 25) + 18;
end;
end;
end;

//filter size as per selected item and container
if dmMain_u.dmMain.qrySize.RecordCount >= 0 then
begin
with dmMain_u.dmMain do
begin
qrySize.Active := False;
qrySize.Params.ParamByName(‘itemselected’).AsString := lsvSearches.Items[lsvSearches.ItemIndex].Text; //lblItemBrand.Text;
qrySize.Params.ParamByName(‘containerselected’).AsString := lsvContainer.Items[lsvContainer.ItemIndex].Text;
qrySize.Active := True;
end;
end;
end;

procedure TformMain.lsvSearchesItemClick(const Sender: TObject;
const AItem: TListViewItem);
begin
aniSearchProcess.Visible := True;
aniSearchProcess.Enabled := True;
{$IFDEF MSWINDOWS}
Application.ProcessMessages;
{$ENDIF}
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
Application.HandleMessage;
{$ENDIF}

tabHome.TabIndex := 2; // move the tab at selection

//always on top at transition
vsbItemProfile.ViewportPosition := PointF(vsbItemProfile.ViewportPosition.X, 0);

//filter variant as per selected item
if dmMain_u.dmMain.qryVariant.RecordCount >= 0 then
begin
with dmMain_u.dmMain do
begin
lytVariant.Visible := False;
lytVariant.Visible := True;
lytVariant.Height := qryVariant.RecordCount * 25; //resizing the listview height according to height of items

qryVariant.Active := False;
qryVariant.Params.ParamByName(‘itemselected’).AsString := lsvSearches.Items[lsvSearches.ItemIndex].Text; //lblItemBrand.Text;
qryVariant.Active := True;
end;
end;

//resizing the size gridlayout according to height container and size items
with dmMain_u.dmMain do
begin
if (qryContainer.RecordCount >= 0) or (qrySize.RecordCount >= 0) then
begin
lytSize.Visible := False;
lytSize.Visible := True;
spdAddToCart.Visible := True;
spdAddToCart.Visible := False;
lytBottomBuffer.Visible := True;
lytBottomBuffer.Visible := False;
vsbItemProfile.Visible := False;
vsbItemProfile.Visible := True;
if ((qryContainer.RecordCount * 25) + 18) >
((qrySize.RecordCount * 25) + 18) then
begin
lytSize.Height := (qryContainer.RecordCount * 25) + 18;
end
else if ((qryContainer.RecordCount * 25) + 18) <
((qrySize.RecordCount * 25) + 18) then
begin
lytSize.Height := (qrySize.RecordCount * 25) + 18;
end
else if (((qryContainer.RecordCount * 25) + 18) =
((qrySize.RecordCount * 25) + 18)) then
begin
lytSize.Height := (qryContainer.RecordCount * 25) + 18;
end;
end;
end;

//filter container as per selected item
if dmMain_u.dmMain.qryContainer.RecordCount >= 0 then
begin
with dmMain_u.dmMain do
begin
qryContainer.Active := False;
qryContainer.Params.ParamByName(‘itemselected’).AsString := lsvSearches.Items[lsvSearches.ItemIndex].Text; //lblItemBrand.Text;
qryContainer.Active := True;
end;
end;

//filter size as per selected item and container
if dmMain_u.dmMain.qrySize.RecordCount >= 0 then
begin
with dmMain_u.dmMain do
begin
qrySize.Active := False;
qrySize.Params.ParamByName(‘itemselected’).AsString := lsvSearches.Items[lsvSearches.ItemIndex].Text; //lblItemBrand.Text;
qrySize.Params.ParamByName(‘containerselected’).AsString := lsvContainer.Items[lsvContainer.ItemIndex].Text;
qrySize.Active := True;
end;
end;

aniSearchProcess.Visible := False;
aniSearchProcess.Enabled := False;
{$IFDEF MSWINDOWS}
Application.ProcessMessages;
{$ENDIF}
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
Application.HandleMessage;
{$ENDIF}
end;

end.

Comments are closed.