英文:
Delphi - Force Component to lay over other Components
问题
在这个Firemonkey表单上,有一个TGridPanelLayout
,它包含多个行和仅一个列。在这个TGridPanelLayout
中有多个TEdit
控件。在顶部的TEdit
控件中,我添加了一个下拉按钮和一个包含ListView的滚动框。当我点击下拉按钮时,我想要滚动框可见。一切都正常工作,除了一个问题,滚动框位于表单上其他Edit字段的后面。我尝试使用BringToFront
来调整滚动框、ListView,甚至是Edit,但没有任何变化。我还尝试了ClipParent
和ClipChild
,但都没有帮助。如何将滚动框和滚动框中的ListView置于最前面?
编辑:
FMX表单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
用于创建和按钮点击的代码,请不要忘记在SpeedButton上定义OnClick事件:
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, FM
<details>
<summary>英文:</summary>
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][1]][1]
[1]: https://i.stack.imgur.com/GYxhi.png
</details>
# 答案1
**得分**: 3
看起来`BringToFront`将控件置于其他具有相同父级的控件的前面。
所以当你在一个窗体上有两个控件,A 和 B,每个都有一个子控件,A1 和 B1,那么为了将 A1 置于 B 的前面,你需要将 A 置于 B 的前面。
在你的情况下,层次结构如下:
* `GridPanelLayout1`
* `Edit1`
* `DropDownEditButton1`
* `VertScrollBox1`
* `ListView1`
* `GridPanelLayout2`
* `Edit2`
* `Edit3`
* `Edit4`
* `Edit5`
为了将 `ListView1` 置于 `Edit2` 和其他编辑控件的前面,`GridPaneLayout1` 需要置于 `GridPanelLayout2` 的前面。
如果你在 `GridPanelLayout1` 下面还有其他控件(即与 `Edit1` 处于相同级别)与 `ListView1` 重叠,那么你还需要将 `Edit1` 置于这些同级控件的前面。
<details>
<summary>英文:</summary>
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.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论