4

我有像这样的 16 x 4 网格面板:

在此处输入图像描述

有时我想隐藏一些行并将底行向上移动。当我将组件可见属性设置为 false 时,布局不会更新:

在此处输入图像描述

然而,行大小类型设置为自动:

在此处输入图像描述

为什么在没有可显示的内容时组件不将行高设置为零?

4

2 回答 2

2

为什么在没有可显示的内容时组件不将行高设置为零?

因为仅当该行的所有列中都没有组件时,该行才被视为空,而不是它们是否可见。所以同样返回IsRowEmpty方法。要解决此问题,单元格组件需要通知您其可见性更改。生成此通知后,您可以像IsRowEmpty方法一样检查该行,但您将检查控件是否可见,而不是检查它们是否已分配。根据这种方法的结果,您可以将 的大小设置Value为 0 以隐藏该行。

在 interposed 类的帮助下,检查行或列中的所有控件是否可见的方法,您可以编写类似这样的内容。当某个行或列中的所有现有控件都可见时,这些方法返回 True,否则返回 False:

uses
  ExtCtrls, Consts;

type
  TGridPanel = class(ExtCtrls.TGridPanel)
  public
    function IsColContentVisible(ACol: Integer): Boolean;
    function IsRowContentVisible(ARow: Integer): Boolean;
  end;

implementation

function TGridPanel.IsColContentVisible(ACol: Integer): Boolean;
var
  I: Integer;
  Control: TControl;
begin
  Result := False;
  if (ACol > -1) and (ACol < ColumnCollection.Count) then
  begin
    for I := 0 to ColumnCollection.Count -1 do
    begin
      Control := ControlCollection.Controls[I, ACol];
      if Assigned(Control) and not Control.Visible then
        Exit;
    end;
    Result := True;
  end
  else
    raise EGridPanelException.CreateFmt(sInvalidColumnIndex, [ACol]);
end;

function TGridPanel.IsRowContentVisible(ARow: Integer): Boolean;
var
  I: Integer;
  Control: TControl;
begin
  Result := False;
  if (ARow > -1) and (ARow < RowCollection.Count) then
  begin
    for I := 0 to ColumnCollection.Count -1 do
    begin
      Control := ControlCollection.Controls[I, ARow];
      if Assigned(Control) and not Control.Visible then
        Exit;
    end;
    Result := True;
  end
  else
    raise EGridPanelException.CreateFmt(sInvalidRowIndex, [ARow]);
end;

第一行显示的用法:

procedure TForm1.Button1Click(Sender: TObject);
begin
  // after you update visibility of controls in the first row...
  // if any of the controls in the first row is not visible, change the 
  // row's height to 0, what makes it hidden, otherwise set certain height
  if not GridPanel1.IsRowContentVisible(0) then
    GridPanel1.RowCollection[0].Value := 0
  else
    GridPanel1.RowCollection[0].Value := 50;
end;
于 2012-12-12T09:46:42.443 回答
0

我有一个 hacky 解决方案...保持 Autosizing

Procedure ShowHideControlFromGrid(C:TControl);
begin
  if C.Parent = nil then
    begin
      c.Parent := TWinControl(c.Tag)
    end
  else
    begin
    c.Tag := NativeInt(C.Parent);
    c.Parent := nil;
    end;
end;

procedure TForm4.Button1Click(Sender: TObject);
begin   // e.g. Call
 ShowHideControlFromGrid(Edit5);
 ShowHideControlFromGrid(Edit6);
 ShowHideControlFromGrid(Edit7);
 ShowHideControlFromGrid(Label1);
end;
于 2012-12-12T12:25:23.700 回答