Search code examples
delphifiremonkeydelphi-11-alexandria

Delphi - Force Component to lay over other Components


I have a Firemonkey Form. On this Form there is a TGridPanelLayout. On that layout with multiple Rows and only one Column. There are several TEdit Controls in that TGridPanelLayout. Into the top TEdit Control I added a dropdown Button and a Scrollbox with a Listview in it. When I click the dropdown Button I want the Scrollbox to be visible. Everything works fine, except the fact, that the Scrollbox is viewed behind the other EditFields on the Form. I try BringToFront with Scrollbox and Listveiw even with the Edit but nothing changes. I Played arround with ClipParent and ClipChild nothing helps. How can I bring the Scrollbox and the Listview in that Scroll Box to Front?

EDIT: Code for FMX Form Unit1:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 569
  ClientWidth = 721
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop]
  OnCreate = FormCreate
  DesignerMasterStyle = 0
  object GridPanelLayout1: TGridPanelLayout
    Align = MostTop
    Size.Width = 721.000000000000000000
    Size.Height = 153.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 0
    ColumnCollection = <
      item
        Value = 100.000000000000000000
      end>
    ControlCollection = <
      item
        Column = 0
        Control = Edit1
        Row = 0
      end>
    RowCollection = <
      item
        Value = 100.000000000000000000
      end>
    object Edit1: TEdit
      Touch.InteractiveGestures = [LongTap, DoubleTap]
      Align = Horizontal
      TabOrder = 2
      Position.Y = 48.000000000000000000
      Size.Width = 721.000000000000000000
      Size.Height = 25.000000000000000000
      Size.PlatformDefault = False
      Caret.Interval = 1
      Caret.Width = 10
      object DropDownEditButton1: TDropDownEditButton
        CanFocus = False
        Cursor = crArrow
        Size.Width = 28.000000000000000000
        Size.Height = 21.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 0
        OnClick = DropDownEditButton1Click
      end
      object VertScrollBox1: TVertScrollBox
        Align = Horizontal
        Position.Y = -16.000000000000000000
        Size.Width = 640.000000000000000000
        Size.Height = 50.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 0
        Visible = False
        Viewport.Width = 640.000000000000000000
        Viewport.Height = 50.000000000000000000
        object ListView1: TListView
          ItemAppearanceClassName = 'TListItemAppearance'
          ItemEditAppearanceClassName = 'TListItemShowCheckAppearance'
          HeaderAppearanceClassName = 'TListHeaderObjects'
          FooterAppearanceClassName = 'TListHeaderObjects'
          EditMode = True
          Align = Client
          Size.Width = 640.000000000000000000
          Size.Height = 50.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 0
        end
      end
    end
  end
  object GridPanelLayout2: TGridPanelLayout
    Align = Client
    Size.Width = 721.000000000000000000
    Size.Height = 416.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 1
    ColumnCollection = <
      item
        Value = 100.000000000000000000
      end>
    ControlCollection = <
      item
        Column = 0
        Control = Edit2
        Row = 0
      end
      item
        Column = 0
        Control = Edit3
        Row = 1
      end
      item
        Column = 0
        Control = Edit4
        Row = 2
      end
      item
        Column = 0
        Control = Edit5
        Row = 3
      end>
    RowCollection = <
      item
        SizeStyle = Absolute
        Value = 50.000000000000000000
      end
      item
        SizeStyle = Absolute
        Value = 50.000000000000000000
      end
      item
        SizeStyle = Absolute
        Value = 50.000000000000000000
      end
      item
        SizeStyle = Absolute
        Value = 50.000000000000000000
      end>
    object Edit2: TEdit
      Touch.InteractiveGestures = [LongTap, DoubleTap]
      Align = Center
      TabOrder = 5
      Size.Width = 721.000000000000000000
      Size.Height = 32.000000000000000000
      Size.PlatformDefault = False
    end
    object Edit3: TEdit
      Touch.InteractiveGestures = [LongTap, DoubleTap]
      Align = Center
      TabOrder = 4
      Size.Width = 721.000000000000000000
      Size.Height = 31.000000000000000000
      Size.PlatformDefault = False
    end
    object Edit4: TEdit
      Touch.InteractiveGestures = [LongTap, DoubleTap]
      Align = Center
      TabOrder = 3
      Size.Width = 721.000000000000000000
      Size.Height = 28.000000000000000000
      Size.PlatformDefault = False
    end
    object Edit5: TEdit
      Touch.InteractiveGestures = [LongTap, DoubleTap]
      Align = Center
      TabOrder = 2
      Size.Width = 721.000000000000000000
      Size.Height = 26.000000000000000000
      Size.PlatformDefault = False
    end
  end
end

Code for Creation and Button Click, dont forget to define OnclickEvent on Speedbutton:

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.Controls.Presentation, FMX.Edit, FMX.Layouts, FMX.StdCtrls, FMX.ListView.Types,
  FMX.ListView.Appearances, FMX.ListView.Adapters.Base, FMX.ListView;

type
  TForm1 = class(TForm)
    GridPanelLayout1: TGridPanelLayout;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    DropDownEditButton1: TDropDownEditButton;
    VertScrollBox1: TVertScrollBox;
    ListView1: TListView;
    GridPanelLayout2: TGridPanelLayout;
    procedure DropDownEditButton1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.DropDownEditButton1Click(Sender: TObject);
begin
  Edit1.BringToFront;
  VertScrollBox1.Position.Y := TSpeedButton(Sender).Height;
  VertScrollBox1.Height := (GridPanelLayout1.Height + GridPanelLayout2.Height) - Edit1.LocalToAbsolute(PointF(0, 0)).Y - Edit1.Height - 10;
  VertScrollBox1.Visible := true;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListView1.Items.Clear;
  for var I := 0 to 100 do
    ListView1.Items.Add.Text := 'Demo ' + I.ToString;

end;

end.

Image of behavior: https://ibb.co/pxTcRWP

enter image description here


Solution

  • It appears that BringToFront brings the control to the front of other controls with the same parent.

    So when you have two controls on a form, A and B, and each has a child control, A1 and B1, then in order to bring A1 in front of B, you need to bring A to the front of B.

    In your case, you have the hierarchy as follows:

    • GridPanelLayout1
      • Edit1
        • DropDownEditButton1
        • VertScrollBox1
          • ListView1
    • GridPanelLayout2
      • Edit2
      • Edit3
      • Edit4
      • Edit5

    In order to bring ListView1 to the front of Edit2 and the other edits, GridPaneLayout1 needs to be in front of GridPanelLayout2.

    If you had other controls directly under GridPanelLayout1 (i.e. at the same level as Edit1) that ListView1 overlapped, then you would also need to bring Edit1 to the front of those sibling controls.