Delphi 如何将单元动态添加到帧';s使用条款?
假设我有一个主窗体。主窗体包含两个按钮(打开和关闭),单击每个按钮可创建一个以主窗体为父/所有者的框架。 框架包含3个按钮(添加、编辑和删除),示例代码如下: 帧代码:Delphi 如何将单元动态添加到帧';s使用条款?,delphi,Delphi,假设我有一个主窗体。主窗体包含两个按钮(打开和关闭),单击每个按钮可创建一个以主窗体为父/所有者的框架。 框架包含3个按钮(添加、编辑和删除),示例代码如下: 帧代码: unit UntFrame; ... type TFmeMain = class(TFrame) procedure AddClick(Sender: TObject); procedure EditClick(Sender: TObject); procedure DeleteClick(S
unit UntFrame;
...
type
TFmeMain = class(TFrame)
procedure AddClick(Sender: TObject);
procedure EditClick(Sender: TObject);
procedure DeleteClick(Sender: TObject);
private ...
public ...
end;
implementation
{$R *.dfm}
uses ...
procedure TFmeMain.AddClick(Sender: TObject);
begin
AddBtnClick;
end;
procedure TFmeMain.EditClick(Sender: TObject);
begin
EditBtnClick;
end;
procedure TFmeMain.DeleteClick(Sender: TObject);
begin
DelBtnClick;
end;
end.
unit UntOpen;
...
procedure AddBtnClick;
procedure EditBtnClick;
procedure DelBtnClick;
implementation
procedure AddBtnClick;
begin
ShowMessage('add open');
end;
procedure EditBtnClick;
begin
ShowMessage('edit open');
end;
procedure DelBtnClick;
begin
ShowMessage('delete open');
end;
end.
unit UntClose;
...
procedure AddBtnClick;
procedure EditBtnClick;
procedure DelBtnClick;
implementation
procedure AddBtnClick;
begin
ShowMessage('add close');
end;
procedure EditBtnClick;
begin
ShowMessage('edit close');
end;
procedure DelBtnClick;
begin
ShowMessage('delete close');
end;
end.
框架使用的3种方法(AddBtnClick、editbtclick和DelBtnClick)存在于两个不同的单元上,即UntOpen和UntClose,但根据所创建的框架,其操作方式有所不同。当单击打开按钮时,框架应使用UntOpen,UntoClose用于从主菜单单击关闭按钮时
打开代码:
unit UntFrame;
...
type
TFmeMain = class(TFrame)
procedure AddClick(Sender: TObject);
procedure EditClick(Sender: TObject);
procedure DeleteClick(Sender: TObject);
private ...
public ...
end;
implementation
{$R *.dfm}
uses ...
procedure TFmeMain.AddClick(Sender: TObject);
begin
AddBtnClick;
end;
procedure TFmeMain.EditClick(Sender: TObject);
begin
EditBtnClick;
end;
procedure TFmeMain.DeleteClick(Sender: TObject);
begin
DelBtnClick;
end;
end.
unit UntOpen;
...
procedure AddBtnClick;
procedure EditBtnClick;
procedure DelBtnClick;
implementation
procedure AddBtnClick;
begin
ShowMessage('add open');
end;
procedure EditBtnClick;
begin
ShowMessage('edit open');
end;
procedure DelBtnClick;
begin
ShowMessage('delete open');
end;
end.
unit UntClose;
...
procedure AddBtnClick;
procedure EditBtnClick;
procedure DelBtnClick;
implementation
procedure AddBtnClick;
begin
ShowMessage('add close');
end;
procedure EditBtnClick;
begin
ShowMessage('edit close');
end;
procedure DelBtnClick;
begin
ShowMessage('delete close');
end;
end.
取消关闭代码:
unit UntFrame;
...
type
TFmeMain = class(TFrame)
procedure AddClick(Sender: TObject);
procedure EditClick(Sender: TObject);
procedure DeleteClick(Sender: TObject);
private ...
public ...
end;
implementation
{$R *.dfm}
uses ...
procedure TFmeMain.AddClick(Sender: TObject);
begin
AddBtnClick;
end;
procedure TFmeMain.EditClick(Sender: TObject);
begin
EditBtnClick;
end;
procedure TFmeMain.DeleteClick(Sender: TObject);
begin
DelBtnClick;
end;
end.
unit UntOpen;
...
procedure AddBtnClick;
procedure EditBtnClick;
procedure DelBtnClick;
implementation
procedure AddBtnClick;
begin
ShowMessage('add open');
end;
procedure EditBtnClick;
begin
ShowMessage('edit open');
end;
procedure DelBtnClick;
begin
ShowMessage('delete open');
end;
end.
unit UntClose;
...
procedure AddBtnClick;
procedure EditBtnClick;
procedure DelBtnClick;
implementation
procedure AddBtnClick;
begin
ShowMessage('add close');
end;
procedure EditBtnClick;
begin
ShowMessage('edit close');
end;
procedure DelBtnClick;
begin
ShowMessage('delete close');
end;
end.
我想在每次创建框架的uses子句时动态地(如果可能的话)添加一个单元,以便单击框架的add、edit或delete按钮触发正确的方法(如果单击Open按钮,则从UntOpen调用方法;如果单击Close按钮,则从UNTOCLOSE调用方法)
还是有更有效的方法
谢谢。您不能动态使用单位;无法在运行时操作uses子句。您似乎想更改单元列表,以便帧的代码(已调用
AddBtnClick
)将神奇地从一个单元或另一个单元中选择函数
德尔福不是那样工作的。如果你真的想要这样的东西,试试Python Delphi单元是一种编译时结构。它们不能在运行时被操纵。在编译时,编译器会看到您对
AddBtnClick
的调用,然后根据您已经使用的单元解析-绑定-名称。以后不能重新绑定该名称
相反,您可以将参数传递给框架类构造函数。将按钮函数放入数据结构中,然后将这些对象传递给帧。(这也称为依赖项注入。)例如,您可以从以下抽象类开始:
type
TButtonBehavior = class
class procedure AddBtnClick; virtual; abstract;
class procedure EditBtnClick; virtual; abstract;
class procedure DelBtnClick; virtual; abstract;
end;
然后,定义框架以接收该类的后代,并根据该值编写按钮处理程序:
type
TButtonBehaviorClass = class of TButtonBehavior;
TMainFrame = class(TFrame)
private
FBehavior: TButtonBehaviorClass;
...
constructor TMainFrame.Create(AOwner: TComponent; ABehavior: TButtonBehaviorClass);
begin
inherited Create(AOwner);
FBehavior := ABehavior;
end;
procedure TMainFrame.AddBtnClick(Sender: TObject);
begin
FBehavior.AddBtnClick;
end;
接下来,为希望框架支持的每个行为集定义抽象类的后代。如果需要,可以在单独的单元中定义它们,但由于它们已经在单独的类中,因此不需要进一步的分离
type
TOpenBehavior = class(TButtonBehavior)
class procedure AddBtnClick; override;
class procedure EditBtnClick; override;
class procedure DelBtnClick; override;
end;
TCloseBehavior = class(TButtonBehavior)
class procedure AddBtnClick; override;
class procedure EditBtnClick; override;
class procedure DelBtnClick; override;
end;
最后,在创建框架的新实例时,将其中一个类传递给框架构造函数
Frame := TMainFrame.Create(Self, TOpenBehavior);
不能动态使用单位;无法在运行时操作uses子句。您似乎想更改单元列表,以便帧的代码(已调用
AddBtnClick
)将神奇地从一个单元或另一个单元中选择函数
德尔福不是那样工作的。如果你真的想要这样的东西,试试Python Delphi单元是一种编译时结构。它们不能在运行时被操纵。在编译时,编译器会看到您对
AddBtnClick
的调用,然后根据您已经使用的单元解析-绑定-名称。以后不能重新绑定该名称
相反,您可以将参数传递给框架类构造函数。将按钮函数放入数据结构中,然后将这些对象传递给帧。(这也称为依赖项注入。)例如,您可以从以下抽象类开始:
type
TButtonBehavior = class
class procedure AddBtnClick; virtual; abstract;
class procedure EditBtnClick; virtual; abstract;
class procedure DelBtnClick; virtual; abstract;
end;
然后,定义框架以接收该类的后代,并根据该值编写按钮处理程序:
type
TButtonBehaviorClass = class of TButtonBehavior;
TMainFrame = class(TFrame)
private
FBehavior: TButtonBehaviorClass;
...
constructor TMainFrame.Create(AOwner: TComponent; ABehavior: TButtonBehaviorClass);
begin
inherited Create(AOwner);
FBehavior := ABehavior;
end;
procedure TMainFrame.AddBtnClick(Sender: TObject);
begin
FBehavior.AddBtnClick;
end;
接下来,为希望框架支持的每个行为集定义抽象类的后代。如果需要,可以在单独的单元中定义它们,但由于它们已经在单独的类中,因此不需要进一步的分离
type
TOpenBehavior = class(TButtonBehavior)
class procedure AddBtnClick; override;
class procedure EditBtnClick; override;
class procedure DelBtnClick; override;
end;
TCloseBehavior = class(TButtonBehavior)
class procedure AddBtnClick; override;
class procedure EditBtnClick; override;
class procedure DelBtnClick; override;
end;
最后,在创建框架的新实例时,将其中一个类传递给框架构造函数
Frame := TMainFrame.Create(Self, TOpenBehavior);
请尝试类似以下内容:
unit UntFrame;
...
type
TFmeMain = class(TFrame)
procedure AddClick(Sender: TObject);
procedure EditClick(Sender: TObject);
procedure DeleteClick(Sender: TObject);
public
OnAdd: procedure;
OnEdit: procedure;
OnDelete: procedure;
end;
implementation
{$R *.dfm}
procedure TFmeMain.AddClick(Sender: TObject);
begin
if Assigned(OnAdd) then OnAdd;
end;
procedure TFmeMain.EditClick(Sender: TObject);
begin
if Assigned(OnEdit) then OnEdit;
end;
procedure TFmeMain.DeleteClick(Sender: TObject);
begin
if Assigned(OnDelete) then OnDelete;
end;
end.
请尝试类似以下内容:
unit UntFrame;
...
type
TFmeMain = class(TFrame)
procedure AddClick(Sender: TObject);
procedure EditClick(Sender: TObject);
procedure DeleteClick(Sender: TObject);
public
OnAdd: procedure;
OnEdit: procedure;
OnDelete: procedure;
end;
implementation
{$R *.dfm}
procedure TFmeMain.AddClick(Sender: TObject);
begin
if Assigned(OnAdd) then OnAdd;
end;
procedure TFmeMain.EditClick(Sender: TObject);
begin
if Assigned(OnEdit) then OnEdit;
end;
procedure TFmeMain.DeleteClick(Sender: TObject);
begin
if Assigned(OnDelete) then OnDelete;
end;
end.
如果我是你,我会尝试以下解决方案:
unit UntFrame;
...
type
TFmeMain = class(TFrame)
procedure AddClick(Sender: TObject);
procedure EditClick(Sender: TObject);
procedure DeleteClick(Sender: TObject);
private ...
public ...
end;
implementation
{$R *.dfm}
uses ...
procedure TFmeMain.AddClick(Sender: TObject);
begin
AddBtnClick;
end;
procedure TFmeMain.EditClick(Sender: TObject);
begin
EditBtnClick;
end;
procedure TFmeMain.DeleteClick(Sender: TObject);
begin
DelBtnClick;
end;
end.
unit UntOpen;
...
procedure AddBtnClick;
procedure EditBtnClick;
procedure DelBtnClick;
implementation
procedure AddBtnClick;
begin
ShowMessage('add open');
end;
procedure EditBtnClick;
begin
ShowMessage('edit open');
end;
procedure DelBtnClick;
begin
ShowMessage('delete open');
end;
end.
unit UntClose;
...
procedure AddBtnClick;
procedure EditBtnClick;
procedure DelBtnClick;
implementation
procedure AddBtnClick;
begin
ShowMessage('add close');
end;
procedure EditBtnClick;
begin
ShowMessage('edit close');
end;
procedure DelBtnClick;
begin
ShowMessage('delete close');
end;
end.
主框架:
unit UntFrame;
...
uses
UntOpen, UntClose, ...;
type
TSelectedPage = (spOpen, spClose);
TFmeMain = class(TFrame)
procedure AddClick(Sender: TObject);
procedure EditClick(Sender: TObject);
procedure DeleteClick(Sender: TObject);
private
FSelectedPage: TSelectedPage;
...
public ...
end;
implementation
{$R *.dfm}
uses ...
procedure TFmeMain.AddClick(Sender: TObject);
begin
case FSelectedPage of:
spOpen: TUntOpen.AddBtnClick;
spClose: TUntClose.AddBtnClick;
end;
end;
procedure TFmeMain.EditClick(Sender: TObject);
begin
case FSelectedPage of:
spOpen: TUntOpen.EditBtnClick;
spClose: TUntClose.EditBtnClick;
end;
end;
procedure TFmeMain.DeleteClick(Sender: TObject);
begin
case FSelectedPage of:
spOpen: TUntOpen.DelBtnClick;
spClose: TUntClose.DelBtnClick;
end;
end;
end.
开放单元:
unit UntOpen;
...
type
TUntOpen = class
public
class procedure AddBtnClick;
class procedure EditBtnClick;
class procedure DelBtnClick;
end;
implementation
class procedure TUntOpen.AddBtnClick;
begin
ShowMessage('add open');
end;
class procedure TUntOpen.EditBtnClick;
begin
ShowMessage('edit open');
end;
class procedure TUntOpen.DelBtnClick;
begin
ShowMessage('delete open');
end;
end.
关闭单元:
unit UntClose;
...
type
TUntClose = class
public
class procedure AddBtnClick;
class procedure EditBtnClick;
class procedure DelBtnClick;
end;
implementation
class procedure TUntClose.AddBtnClick;
begin
ShowMessage('add close');
end;
class procedure TUntClose.EditBtnClick;
begin
ShowMessage('edit close');
end;
class procedure TUntClose.DelBtnClick;
begin
ShowMessage('delete close');
end;
end.
这是一种OOP方法来实现您想要实现的目标,在Delphi中是可能的。如果我是您,我会尝试以下解决方案:
unit UntFrame;
...
type
TFmeMain = class(TFrame)
procedure AddClick(Sender: TObject);
procedure EditClick(Sender: TObject);
procedure DeleteClick(Sender: TObject);
private ...
public ...
end;
implementation
{$R *.dfm}
uses ...
procedure TFmeMain.AddClick(Sender: TObject);
begin
AddBtnClick;
end;
procedure TFmeMain.EditClick(Sender: TObject);
begin
EditBtnClick;
end;
procedure TFmeMain.DeleteClick(Sender: TObject);
begin
DelBtnClick;
end;
end.
unit UntOpen;
...
procedure AddBtnClick;
procedure EditBtnClick;
procedure DelBtnClick;
implementation
procedure AddBtnClick;
begin
ShowMessage('add open');
end;
procedure EditBtnClick;
begin
ShowMessage('edit open');
end;
procedure DelBtnClick;
begin
ShowMessage('delete open');
end;
end.
unit UntClose;
...
procedure AddBtnClick;
procedure EditBtnClick;
procedure DelBtnClick;
implementation
procedure AddBtnClick;
begin
ShowMessage('add close');
end;
procedure EditBtnClick;
begin
ShowMessage('edit close');
end;
procedure DelBtnClick;
begin
ShowMessage('delete close');
end;
end.
主框架:
unit UntFrame;
...
uses
UntOpen, UntClose, ...;
type
TSelectedPage = (spOpen, spClose);
TFmeMain = class(TFrame)
procedure AddClick(Sender: TObject);
procedure EditClick(Sender: TObject);
procedure DeleteClick(Sender: TObject);
private
FSelectedPage: TSelectedPage;
...
public ...
end;
implementation
{$R *.dfm}
uses ...
procedure TFmeMain.AddClick(Sender: TObject);
begin
case FSelectedPage of:
spOpen: TUntOpen.AddBtnClick;
spClose: TUntClose.AddBtnClick;
end;
end;
procedure TFmeMain.EditClick(Sender: TObject);
begin
case FSelectedPage of:
spOpen: TUntOpen.EditBtnClick;
spClose: TUntClose.EditBtnClick;
end;
end;
procedure TFmeMain.DeleteClick(Sender: TObject);
begin
case FSelectedPage of:
spOpen: TUntOpen.DelBtnClick;
spClose: TUntClose.DelBtnClick;
end;
end;
end.
开放单元:
unit UntOpen;
...
type
TUntOpen = class
public
class procedure AddBtnClick;
class procedure EditBtnClick;
class procedure DelBtnClick;
end;
implementation
class procedure TUntOpen.AddBtnClick;
begin
ShowMessage('add open');
end;
class procedure TUntOpen.EditBtnClick;
begin
ShowMessage('edit open');
end;
class procedure TUntOpen.DelBtnClick;
begin
ShowMessage('delete open');
end;
end.
关闭单元:
unit UntClose;
...
type
TUntClose = class
public
class procedure AddBtnClick;
class procedure EditBtnClick;
class procedure DelBtnClick;
end;
implementation
class procedure TUntClose.AddBtnClick;
begin
ShowMessage('add close');
end;
class procedure TUntClose.EditBtnClick;
begin
ShowMessage('edit close');
end;
class procedure TUntClose.DelBtnClick;
begin
ShowMessage('delete close');
end;
end.
这是一种OOP方法,可以实现您想要实现的目标,而且在Delphi中是可能的。重新思考您的设计。这是一场维护噩梦,毫无意义。相反,使用单独的框架,并将逻辑放在它所属的位置。它不仅可以在设计器中正常工作,而且可以防止将来给您(以及任何其他必须尝试和维护您的代码的人)带来重大麻烦,这始终是一个好主意(除非您持有主要止痛药制造商的股票)。不相关,但请考虑使用Action Manager。在设计一个好的GUI时,操作是您的朋友,但您不必在uses子句中动态地包含一个单元。不同的单元被编译到应用程序中,这取决于哪些单元依赖于哪些其他单元。你的单位是否使用它取决于设计。如果应用程序中的某个单元已经在其他地方使用过,那么再次使用它也没什么坏处。请重新考虑您的设计。这是一场维护噩梦,毫无意义。相反,使用单独的框架,并将逻辑放在它所属的位置。它不仅可以在设计器中正常工作,而且可以防止将来给您(以及任何其他必须尝试和维护您的代码的人)带来重大麻烦,这始终是一个好主意(除非您持有主要止痛药制造商的股票)。不相关,但请考虑使用Action Manager。在设计一个好的GUI时,动作是你的朋友,但你不一定要在c中包含一个单元