You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行时创建TMemo如何匹配父控件宽度?构造函数Width为0原因

问题解答:构造函数中Self.Width为0的原因及解决方法

为什么构造函数里Self.Width是0?

在VCL框架中,控件的尺寸属性(如Width、Height)不会在构造函数执行时完成初始化。当你在TCustomTabSheet的构造函数中创建实例时,这个控件还未被添加到父容器(比如TPageControl),也没接收到窗口初始化的布局消息,此时它的尺寸保持默认初始值0。只有当控件被添加到父容器后,父容器才会根据自身布局逻辑为子控件分配尺寸,或通过后续窗口重绘、Resize事件触发尺寸更新。

另外注意你代码里的拼写错误:Memo.Heigth应该是Memo.Height。

实现子控件与父控件宽度同步的正确方法

不要在构造函数中设置子控件宽度,而是通过重写Resize方法实现——Resize方法会在控件尺寸变化时被调用(包括第一次初始化尺寸),此时Self.Width已经是正确的父控件宽度值。

修改后的完整代码如下:

type
  TCustomTabSheet = class(TTabSheet)
  public
    constructor Create(AOwner : TComponent); override;
  protected
    procedure Resize; override; // 新增Resize方法重写
  public
    Memo : TMemo;
  end;

implementation

constructor TCustomTabSheet.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  Memo := TMemo.Create(Self);
  Memo.Parent := Self;
  Memo.Left := 1;
  Memo.Top := 1;
  Memo.Height := 100; // 修正拼写错误
  Memo.Name := 'TestMemo';
  // 此处不再设置Width,交给Resize方法处理
end;

procedure TCustomTabSheet.Resize;
begin
  inherited Resize; // 先执行父类的Resize逻辑
  if Assigned(Memo) then
  begin
    // 减去2是因为Left设为1,左右各留1像素边距,避免超出父控件
    Memo.Width := Self.Width - 2;
    // 如果需要高度随父控件变化,可添加以下代码
    // Memo.Height := Self.Height - 2;
  end;
end;

如果使用TStringGrid,逻辑完全相同,只需把TMemo替换为TStringGrid即可。

内容的提问来源于stack exchange,提问作者ZinkPT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 12:42:37