【发布时间】:2015-02-23 01:09:40
【问题描述】:
我正在使用 RAD Studio XE5 构建我的应用程序。
我发现尝试在 TForm 上发布属性不是很实用。然后它必须注册并安装为一个包,那么它对于大量的开发是不切实际的。
因此,我决定创建一个非可视组件 (TFormPropertiesEditor),用于填充表单属性。一种标准化我的表格的方法。
组件将被放置在基本表单上,其他所有表单都继承该表单(我们称之为 TBaseForm)。因此,该组件只会在“基础”表单上删除一次,然后通过继承,其他所有表单也会拥有它。
创建的组件将检测其所有者的类(BaseForm 或其后代)并创建一个可通过“Properties”属性访问的对象,该对象的类将取决于所有者类。
这样,当检查 TBaseForm 上的组件时,我只能访问 TBaseFormProperties。检查 TSecondForm 上的组件时,我还可以访问 TSecondFormProperties。只是,该组件将足够智能以检测它应该将哪个 PropertyClass 公开为 Properties 属性。
组件将通过GetPropertiesClass检查表单,定义为:
function TBaseForm.GetPropertiesClass : TPropertiesClass;
begin
Result := TBaseFormProperties;
end;
function TSecondForm.GetPropertiesClass : TPropertiesClass;
begin
Result := TSecondFormProperties;
end;
每个表单都有一个对应的 TProperties 后代,如下所示:
TBaseForm ------------ TSecondForm ------------- ...
|
TBaseFormProperties -- TSecondFormProperties --- ...
例如:
如果放置组件的 Form 是 TBaseForm,则 FProperties 将是 TBaseFormProperties。如果表单是 TSecondForm,则 FProperties 将是 TSecondFormProperties。自然地,TSecondFormProperties 将继承自 TBaseFormProperties。
不过,当我将组件放在表单上时,似乎无法检测到该组件是哪个类。
function TFormPropertiesEditor.GetPropertiesClass: TFormPropertiesClass;
begin
Result := TBaseForm(Owner).GetPropertiesClass;
end;
看起来是 TBaseForm(Owner) 部分导致了问题。解释器卡在 TBaseForm 上,不会考虑 Owner 是 TSecondForm 还是 TThirdForm 类型。
接口
所以,为了绕过 TBaseForm(Owner) 类型转换,我决定使用接口。因此,如果我使用声明 GetPropertiesClass 的接口:
IMasterForm = interface(IInterface)
['{B6122F34-65C4-4701-8A5E-50C8DABF5516}']
function GetPropertiesClass : TFormPropertiesClass;
end;
type
TBaseForm = class(TForm, IMasterForm)
MyFormPropertiesEditor1: TMyFormPropertiesEditor;
private
{ Déclarations privées }
public
function GetPropertiesClass : UCommon.TFormPropertiesClass;
end;
以下内容:
function TFormPropertiesEditor.GetPropertiesClass : TFormPropertiesClass;
begin
Result := (Owner as IMasterForm).GetPropertiesClass;
end;
导致不支持接口错误。
抽象祖先方法
然后,我决定添加一个额外的祖先层。我添加了一个类 TMasterForm,TBaseForm 继承自该类。此 TMasterForm 将 GetPropertiesClass 声明为抽象和虚拟:
TMasterForm = class(TForm, IMasterForm)
public
function GetPropertiesClass : TFormPropertiesClass; virtual; abstract;
end;
type
TBaseForm = class(TMasterForm)
private
{ Déclarations privées }
public
function GetPropertiesClass : UCommon.TFormPropertiesClass; override;
end;
但是,我得到了一个 AV,因为我认为 IDE 试图访问 TMasterClass.GetPropertiesClass,这当然没有实现。
如何实现这种类型转换?知道我该怎么做吗?
非常感谢您
【问题讨论】:
-
您没有在 IDE 中注册基本表单。因此,在设计时,您看到的表单不是
TBaseForm类型。你正在尝试的东西是行不通的。我认为你所有的工作都是徒劳的。回到绘图板。 -
也许你需要
RegisterCustomModule... -
@DavidHeffernan 我不认为他会以错误的方式解决这个问题。某些组件的自定义属性编辑器是否使用类似的方法。
-
@Silver 我看不到 IDE 将如何实例化 TBaseForm 或任何派生类。它怎么知道这样做?
-
关于你的编辑,你读过我的 cmets 吗? IDE 将如何执行您的代码?
标签: delphi vcl design-time