Question

I have grid panel 16 x 4 like this one:

enter image description here

Sometimes i want to hide some rows and to move bottom rows up. When I set component visible property to false the layout is not updated:

enter image description here

Nevertheless the row size type is set to auto:

enter image description here

Why the component don't set row height to zero when there is nothing to display?

Was it helpful?

Solution

Why the component don't set row height to zero when there is nothing to display ?

Because the row is considered as empty only if there are no components in all columns in that row, not if they're visible or not. So the same returns the IsRowEmpty method. To workaround this, you'd need to be notified by the cell component about its visibility change. When this notification is generated, you can check the row just like the IsRowEmpty method does, except you'll check if the controls are visible, not if they're assigned. Based on the result of such method, you can then set the size of the Value to 0 to hide the row.

With a help of interposed class, the method for checking if all controls in a row or column are visible, you might write something like this. Those methods return True, when all existing controls in a certain row or column are visible, False otherwise:

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;

And the usage shown for the first row:

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;

OTHER TIPS

I've got a hacky solution ... keeping the 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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top