我正在寻找可与D5一起使用的TFlowPanel(或类似)的实现.
基本上我需要TFlowPanel在TScrollBox内部工作(使用Vertical滚动条),因此控件将根据TScrollBox的Width进行换行.
基本上我需要TFlowPanel在TScrollBox内部工作(使用Vertical滚动条),因此控件将根据TScrollBox的Width进行换行.
图像基本上显示了我需要的东西:
调整大小后,控件会自动重新定位:
使用垂直滚动条:
解决方法
只是一个概念.没有各种FlowTypes,也没有可能改变控件的顺序.您仍然可以通过更改DFM中的顺序来移动它们,我认为或通过重置父级.
面板垂直尺寸适合所有控件.这意味着,当您将其放入滚动框时,它将自动工作.
unit uAlignPanel; interface uses Windows,SysUtils,Classes,Controls,ExtCtrls; type TAlignPanel = class(TPanel) protected procedure SetChildOrder(Child: TComponent; Order: Integer); overload; override; procedure SetZOrder(TopMost: Boolean); override; public procedure AlignControls(AControl: TControl; var Rect: TRect); override; procedure Insert(AControl: TControl); procedure Append(AControl: TControl); function GetChildOrder(Child: TControl): Integer; procedure SetChildOrder(Child: TControl; Order: Integer); reintroduce; overload; virtual; procedure MoveChildBefore(Child: TControl; Sibling: TControl); virtual; end; procedure Register; implementation procedure Register; begin RegisterComponents('StackOverflow',[TAlignPanel]); end; { TAlignPanel } procedure TAlignPanel.AlignControls(AControl: TControl; var Rect: TRect); var i: Integer; x,y: Integer; LineHeight: Integer; begin x := 0; y := 0; LineHeight := 0; for i := 0 to ControlCount - 1 do begin if x + Controls[i].Width > ClientWidth then begin x := 0; y := y + LineHeight; LineHeight := 0; end; Controls[i].Top := y; Controls[i].Left := x; x := x + Controls[i].Width; if Controls[i].Height > LineHeight then LineHeight := Controls[i].Height; end; // Height + 1. Not only looks nices,but also prevents a small redrawing // problem of the bottom line of the panel when adding controls. ClientHeight := y + LineHeight + 1; end; procedure TAlignPanel.Append(AControl: TControl); begin AControl.Parent := Self; AControl.BringToFront; Realign; end; function TAlignPanel.GetChildOrder(Child: TControl): Integer; begin for Result := 0 to ControlCount - 1 do if Controls[Result] = Child then Exit; Result := -1; end; procedure TAlignPanel.Insert(AControl: TControl); begin AControl.Parent := Self; AControl.SendToBack; Realign; end; procedure TAlignPanel.MoveChildBefore(Child,Sibling: TControl); var CurrentIndex: Integer; NewIndex: Integer; begin if Child = Sibling then raise Exception.Create('Child and sibling cannot be the same'); CurrentIndex := GetChildOrder(Child); if CurrentIndex = -1 then raise Exception.CreateFmt( 'Control ''%s'' is not a child of panel ''%s''',[Sibling.Name,Name]); if Sibling <> nil then begin NewIndex := GetChildOrder(Sibling); if NewIndex = -1 then raise Exception.CreateFmt( 'Sibling ''%s'' is not a child of panel ''%s''',Name]); if CurrentIndex < NewIndex then Dec(NewIndex); end else NewIndex := ControlCount; SetChildOrder(Child,NewIndex); end; procedure TAlignPanel.SetChildOrder(Child: TComponent; Order: Integer); begin inherited; Realign; end; procedure TAlignPanel.SetChildOrder(Child: TControl; Order: Integer); begin SetChildOrder(TComponent(Child),Order); end; procedure TAlignPanel.SetZOrder(TopMost: Boolean); begin inherited; Realign; end; end.