我很难让Delphi 2006为TFrame上独立的组件分配事件处理程序。
假设我有一个包含TCombo Combo1
的帧TComboFrame
,我在主窗体上的几个位置使用它
当我将TComboFrame MyFrame1
的实例放置到我的主窗体上,并且我想分配一个事件处理程序,我通过点击里面的TCombo来完成我放置在表单上的框架MyFrame1
,然后双击空框对象检查器"事件"选项卡中的OnChange
字段。
通常创建一个新的处理程序,其名称如下:
procedure TMainForm.MyFrame1Combo1Change(Sender: TObject);
并且事件处理程序名称是从祖先TComboFrame上的组件的名称(Combo1
)和我已放置在我的表单上的实例的名称(MyFrame1
)导出的,即对于TComboFrame的那个实例是唯一的。那我就可以了对我放置在主干上的框架的其他实例执行此操作表单,并且它们各自都有自己的事件处理程序。
如果我想要一个为帧的所有实例触发的事件处理程序,我会打开祖先的框架并在那里完成它。
这是我对它应该如何工作的理解,但有些事情哪里出了问题。在我的主框架上的几个实例中形式,有些有自己的事件处理程序,有些有一个通用的事件处理软件
procedure TDMainForm.ComboFrame1Combo1Change(Sender: TObject);
我所尝试的一切都没有打破德尔福与之之间的这种虚幻联系这个由几个帧共享的公共事件处理程序。
我该如何修复这种状态,首先是什么原因导致的?
**更新1**
在阅读了回复和一些实验后,我发现我可以通过以下程序修复有问题的组件:
1) 删除该帧的所有事件处理程序
2) 删除框架,记住其名称
3) 复制另一个已知正常的事件(即具有自己的"单独"事件名称)
4) 将那个粘贴到您删除的位置
5) 恢复原始名称
6) 创建事件处理程序。
至少,它至少对我起过一次作用。。。
**更新2*
另一种解决方法似乎是用一个新的唯一名称重写它在对象检查器中双击空事件字段时创建的事件处理程序名称,然后再次双击该名称。然后Delphi创建一个具有唯一名称的空处理程序。
我会在框架中写入另一个事件,并在我想要另一个OnChange事件时设置它,如下所示:
type
TFrame2 = class(TFrame)
ComboBox1: TComboBox;
procedure ComboBox1Change(Sender: TObject);
private
FMyChangeEvent: TNotifyEvent;
public
property MyChangeEvent: TNotifyEvent read FMyChangeEvent write FMyChangeEvent
end;
implementation
{$R *.dfm}
procedure TFrame2.ComboBox1Change(Sender: TObject);
begin
//Your default combo behavior here
if Assigned(FMyChangeEvent) then
FMyChangeEvent(Self);
end;
我需要在OnChange行为中添加一些内容:
type
TForm1 = class(TForm)
MyLittleFrame: TFrame2;
private
procedure MyOwnCustomLittleOnChangeBehavior(Sender: TObject);
public
constructor Create(AOwner: TComponent); override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
constructor TForm1.Create(AOwner: TComponent);
begin
inherited;
MyLittleFrame.MyChangeEvent := MyOwnCustomLittleOnChangeBehavior;
end;
procedure TForm1.MyOwnCustomLittleOnChangeBehavior(Sender: TObject);
begin
ShowMessage('42');
end;
我通常这样做是因为我不信任在DFM中设置事件的delphi方式,它很容易在没有注意到的情况下删除整个事件。
只需单击要断开链接的TCombo
,在对象检查器中清除其OnClick
事件处理程序分配,然后双击该事件以生成新的事件处理程序。当然,如果生成的事件处理程序名称已经存在,它将被重新使用,但至少对象检查器在生成事件时会重新评估所有对象名称。
当然,这不是一个非常面向对象的方法。法比奥的建议是一个更好的选择。尽管我建议将TFrame
事件声明为published
而不是public
,这样您就可以像其他事件一样在设计时分配它。
我无法在Delphi6或Delphi2009中重新创建这种行为。在我看来,有很多帧(可能会更改它们的名称添加和删除),你已经愚弄/混淆了Delphi的命名约定,它默认使用该约定来链接事件,并且帧最终使用了与以前相同的名称。
因此,双击事件处理程序只会将您放在一个与先前删除(或重命名)的帧创建的事件处理程序同名的事件处理器处(但删除该帧不会删除旧事件处理程序。IYSWIM:)
因此,我的答案是,你会因为得到框架名称而感到困惑;事件处理程序名称混乱!