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

FMX自定义TEdit重写DoChange失败,需保留继承OnChange代码

FMX自定义TEdit:正确实现OnChange扩展逻辑(不覆盖原有OnChange属性)

问题根源

你遇到的编译错误是因为FMX与VCL的控件架构不同:VCL的TCustomEdit直接暴露了DoChange方法供重写,但FMX把这个触发逻辑封装到了控件的Model层——也就是TCustomEdit.Model对应的TCustomEditModel类中,所以直接在TEdit子类里重写DoChange会提示基类无此方法。

解决方案

下面提供两种可行的实现方式,按需选择:


方案一:重写Changed方法(最简单直接)

TCustomEdit提供了Changed保护方法,文本变化时会自动调用它,内部会触发Model的DoChange和OnChange事件。重写这个方法可以在保留原有逻辑的基础上,轻松加入自定义处理。

完整代码:

unit Unit1;

interface

uses
  System.SysUtils, System.Classes, FMX.Edit, FMX.Controls, FMX.Types;

type
  TMyCustomEdit = class(TEdit)
  protected
    procedure Changed; override; // 替换DoChange的重写逻辑
  public
    constructor Create(AOwner: TComponent); override;
  end;

procedure Register;

implementation

uses FMX.Dialogs; // 用于ShowMessage弹窗

procedure Register;
begin
  RegisterClass(TMyCustomEdit);
end;

constructor TMyCustomEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  // 可在此设置控件默认属性
end;

procedure TMyCustomEdit.Changed;
begin
  // 先执行基类逻辑,确保原有OnChange事件及默认行为正常运行
  inherited Changed;

  // 自定义业务逻辑
  if Text = 'Special' then
  begin
    ShowMessage('自定义逻辑触发:检测到文本"Special"');
  end;
end;

end.

方案二:自定义Model并重写DoChange(贴近FMX架构设计)

如果需要深入控件底层逻辑,可以自定义Model类,重写其DoChange方法,再让控件使用这个自定义Model。

完整代码:

unit Unit1;

interface

uses
  System.SysUtils, System.Classes, FMX.Edit, FMX.Controls, FMX.Types, FMX.Edit.Model;

// 自定义Edit Model,重写DoChange
type
  TMyEditModel = class(TCustomEditModel)
  protected
    procedure DoChange; override;
  end;

  TMyCustomEdit = class(TEdit)
  protected
    function CreateModel: TCustomEditModel; override; // 替换默认Model
  public
    constructor Create(AOwner: TComponent); override;
  end;

procedure Register;

implementation

uses FMX.Dialogs;

procedure Register;
begin
  RegisterClass(TMyCustomEdit);
  RegisterClass(TMyEditModel);
end;

constructor TMyCustomEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
end;

function TMyCustomEdit.CreateModel: TCustomEditModel;
begin
  // 返回自定义的Model实例
  Result := TMyEditModel.Create(Self);
end;

procedure TMyEditModel.DoChange;
begin
  // 先执行基类DoChange,保证原有OnChange事件正常触发
  inherited DoChange;

  // 通过Model的Owner获取控件实例,执行自定义逻辑
  if TMyCustomEdit(Owner).Text = 'Special' then
  begin
    ShowMessage('Model层DoChange触发:检测到文本"Special"');
  end;
end;

end.

说明

  • 方案一适合绝大多数场景,代码简洁,无需接触FMX的Model-View架构细节;
  • 方案二更适合需要深度定制控件底层行为的场景,完全遵循FMX的设计模式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 23:13:12