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

如何将TWinControl组件的Name赋值给Caption属性

解决TWinControl自定义组件创建时Caption无法获取Name的问题

组件的Name属性并非在构造函数Create执行期间赋值,而是在构造函数完成后由组件所有者(如Form)分配,所以你在Create里直接读取Name会得到空值。以下是几种可行的解决方案:

方法1:重写Loaded方法

当组件完成DFM加载或设计时初始化后,Loaded方法会被调用,此时Name已被正确赋值。可以在这里同步Caption与Name(仅当Caption未手动设置时):

首先在类声明中添加Loaded方法的重写:

public
  procedure Loaded; override;

然后实现该方法:

procedure TMappLabelTest.Loaded;
begin
  inherited Loaded;
  if FCaption.IsEmpty then
    FCaption := Name;
end;

方法2:重写SetName方法

监听Name属性的赋值操作,当Name被设置时自动同步到Caption(同样仅在Caption未手动修改时):

在类声明中添加SetName的重写:

protected
  procedure SetName(const Value: TComponentName); override;

实现代码:

procedure TMappLabelTest.SetName(const Value: TComponentName);
begin
  inherited SetName(Value);
  if FCaption.IsEmpty then
    FCaption := Value;
end;

方法3:兼容设计时与运行时的完整方案

如果需要同时覆盖设计时拖放组件、运行时动态创建等场景,结合上述两种方法并添加手动设置标记会更稳妥:

完整的类实现代码:

unit MappLabelTest;

interface

uses
  Winapi.Windows, Winapi.Messages, Vcl.Dialogs,
  Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Controls, Vcl.Graphics, Vcl.Forms, Vcl.Themes, Vcl.ComCtrls,
  System.Classes, System.SysUtils, System.Types;

type
  [ComponentPlatformsAttribute(pidWin32 or pidWin64)]
  TMappLabelTest = class(TWinControl)
  private
    FCaption: TCaption;
    FCaptionManuallySet: Boolean; // 标记Caption是否被手动设置过
    procedure SetCaption(const AValue: TCaption);
  protected
    procedure SetName(const Value: TComponentName); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Loaded; override;
  published
    property Caption: TCaption read FCaption write SetCaption;
  end;

implementation

constructor TMappLabelTest.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ParentBackground := True;
  Width := 121;
  Height := 21;
  FCaptionManuallySet := False;
end;

destructor TMappLabelTest.Destroy;
begin
  inherited Destroy;
end;

procedure TMappLabelTest.SetCaption(const AValue: TCaption);
begin
  if FCaption <> AValue then
  begin
    FCaption := AValue;
    FCaptionManuallySet := True; // 手动设置后标记,避免被Name覆盖
  end;
end;

procedure TMappLabelTest.SetName(const Value: TComponentName);
begin
  inherited SetName(Value);
  // 仅当Caption未手动设置且当前为空时,同步Name
  if not FCaptionManuallySet and FCaption.IsEmpty then
    FCaption := Value;
end;

procedure TMappLabelTest.Loaded;
begin
  inherited Loaded;
  if not FCaptionManuallySet and FCaption.IsEmpty then
    FCaption := Name;
end;

end.

关键说明

  • FCaptionManuallySet变量用于区分用户手动设置的Caption和自动同步的Caption,避免后续Name变更覆盖用户自定义内容。
  • 设计时拖放组件到Form时,SetName会触发同步;运行时从DFM加载组件时,Loaded方法会完成初始化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 19:18:17