在自动调整控件高度然后最大化窗体后,如何使主窗体正确对齐?

How can I make the main form align correctly after my control height is autosized and then I maximize the form?

这个我真的不知道怎么解决...

如何重现问题:

运行 代码和缩小 window 直到 DriveBar 的高度增加,然后最大化 window。然后你会注意到 Panel1 不再顶部对齐,并且在这两个面板之间是一个空的 space。我尝试调用 Parent.Realign 但没有成功。你能帮帮我吗?

UnitMain.pas

unit UnitMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, ExtCtrls;

type

  TDriveBar = class(TCustomPanel)
  private
   procedure AutoHeight;
   procedure OnBarResize(Sender:TObject);
  public
   constructor Create(AOwner: TComponent); override;
   property Caption;
  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;
  Drives: TDriveBar;
  Panel1: TPanel;

implementation

{$R *.dfm}

//---------- TDriveBar --------------------------------

constructor TDriveBar.Create(AOwner: TComponent);
begin
 inherited;
 OnResize:=OnBarResize;
end;

procedure TDriveBar.OnBarResize(Sender: TObject);
begin
 AutoHeight;
 Parent.Realign;
end;

procedure TDriveBar.AutoHeight;
begin
 if Width<400 then Height:=100 else Height:=50;
end;

//---------- TForm1 -----------------------------------

procedure TForm1.FormCreate(Sender: TObject);
begin
  Drives:=TDriveBar.Create(Form1);
  Drives.Parent:=Form1;
  Drives.Caption:='DriveBar';
  Panel1:=TPanel.Create(Form1);
  Panel1.Parent:=Form1;
  Panel1.Caption:='Panel1';

  Panel1.Align:=alTop;
  Drives.Align:=alTop;
end;

end.

UnitMain.dfm

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 334
  ClientWidth = 618
  Color = clBtnFace
  DoubleBuffered = True
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poScreenCenter
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
end

首先,永远不要让控件处理自己的事件属性。事件属性是为组件的消费者准备的,而不是为开发人员准备的。组件开发人员对 OnResize 事件的挂钩是受保护的 Resize 方法。如果您想了解 OnResize 相关事件,请覆盖它。

但是,我怀疑您的问题的根源在于,您是在通知大小已更改的事件中更改组件的大小。这很可能是从表单当前尝试移动和调整控件大小的过程中调用的,并且表单会尽其所能避免递归重新对齐请求。

而是重写 CanResize 方法。它以建议的新控件大小调用。您可以调整尺寸,或通过返回 False 完全拒绝调整大小。确保也调用继承的方法。

function TDriveBar.CanResize(var NewWidth, NewHeight: Integer): Boolean;
begin
  if NewWidth < 400 then NewHeight := 100 else NewHeight := 50;
  Result := inherited CanResize(NewWidth, NewHeight);
end;