Delphi Firemonkey TFlowLayout自动调整高度到内容

时间:2015-02-06 15:59:57

标签: delphi layout firemonkey delphi-xe7

我正在使用TFlowLayout来显示多个框。 调整屏幕大小时,FlowLayout会自动调整每行的方框数。 但是我想自动调整周围元素(TTreeViewItem)的高度。 我通过添加一个事件来实现这一目标:

procedure TDeviceTreeView.DeviceTreeViewResize(Sender: TObject);
  begin
    height := ChildrenRect.Height;
  end;

这是中途工作:当流布局中的元素需要更多行时,调整大小以增大。 然而它永远不会缩小。

2 个答案:

答案 0 :(得分:1)

我知道为什么。如果你看一下TControl.GetChildrenRect,你会看到:

function TControl.GetChildrenRect: TRectF;
var
  I: Integer;
  Control: TControl;
begin
  Result := AbsoluteRect;
  { children }
  if not (ClipChildren or SmallSizeControl) and (FControls <> nil) then
    for I := GetFirstVisibleObjectIndex to GetLastVisibleObjectIndex - 1 do
    begin
      Control := FControls[I];
      if Control.Visible then
        Result := UnionRect(Result, Control.GetChildrenRect);
    end
end;

请注意,基本矩形为:

 Result := AbsoluteRect;

从中它将遍历子控件,始终将(union)添加到第一个rect。 这会导致您遇到的行为:如果ChildControl的rect超过FlowLayout的矩形,它会增加,但永远不会减少,因为FlowLayout.AbsoluteRect是函数中的起始矩形。

您可以通过简单的方式解决这个问题,即计算&#34; ChildRect&#34;自己。

procedure TDeviceTreeView.DeviceTreeViewResize(Sender: TObject);
var childrenRect: TRectF;
begin
  if ((csLoading in FlowLayout1.ComponentState) = False) then // You might want to check for csLoading to avoid unecessary calls to resize
  begin
    childrenRect := TRectF.Empty;
    for i := 0 to FlowLayout1.ControlsCount - 1 do
      childrenRect := TRectF.Union(childrenRect, FlowLayout1.Controls[i].ChildrenRect);
    FlowLayout1.Height := childrenRect.Height;
  end;
end;

答案 1 :(得分:0)

您需要设置TTreeViewItem属性Align:alTop。在FMX中,它看起来像:TTreeViewItem.Align:= talignlayout(1);