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
相关产品推荐
相关产品推荐

