我正在使用RAD Studio XE5来构建我的应用程序。
我看到在TForm上尝试tu发布属性是不太实际的。然后它必须作为一个包注册和安装,然后它对于繁重的开发是不实际的。
所以,我决定创建一个用于填充表单属性的非可视组件( TFormPropertiesEditor )。一种标准化表单的方法。
组件将被删除在基本表单上,其他表单继承的形式(让我们称之为TBaseForm)。所以,组件只会在“基础”表单上删除一次,然后继承,其他每种形式都会有它。
创建的组件将检测其所有者的类(BaseForm或其后代)并创建可通过“属性”属性访问的对象,该属性的类将以所有者类为条件。
这样,在TBaseForm上检查组件时,我只能访问TBaseFormProperties。在TSecondForm上检查组件时,我也可以访问TSecondFormProperties。只是,该组件足够智能,可以检测它应该公开哪个PropertyClass作为属性属性。
组件将通过 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(所有者)部分导致了问题。解释器停留在TBaseForm上,并且不会考虑所有者是否为TSecondForm或TThirdForm类型。
接口
因此,为了绕过TBaseForm(所有者)类型转换,我决定使用一个接口。所以如果我使用一个声明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声明为abstract和virtual:
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,当然没有实现。
如何完成此TypeCasting?我知道怎么办?
非常感谢您提前
答案 0 :(得分:2)
这里的基本问题是IDE不会在设计时实例化您的表单。因此,无论您在表单类中放入什么代码,它都不会由IDE执行。这是因为您没有在IDE中注册表单。
如果您希望IDE了解您的表单,则需要在IDE中注册它们。那时你的所有代码都变得不必要,因为你回到了你想要避免的事情上。即使用IDE注册表单。你陷入了Catch 22的境地。如果您需要IDE了解表单,则需要注册它们。此时,您也可以直接在Object Inspector中显示属性。
答案 1 :(得分:-1)
代码中的问题是您没有正确继承GetPropertiesClass方法。
事实上,你并没有在班级家庭中继承它。
在您的代码中,每个类类型都有自己的GetPropertiesClass方法版本,因此您将所有者类型转换为TBaseForm类,即使Owner属于TSecondForm类,也会使用TBaseForm中的方法。
因此,您需要确保TBaseForm类中的GetPropertiesClass是虚拟的,并且TSecondForm中的merhod GetPropertiesClass被覆盖。
这将确保即使在所有者为TSeconfForm类时将所有者类型转换为TBaseClass,也将调用TSecondForm.GetProperties方法。