如何强制TFrame上的组件拥有自己的事件处理程序?

时间:2012-04-06 00:32:25

标签: delphi event-handling delphi-2006 tframe

我很难让Delphi 2006将事件处理程序分配给独立的TFrame上的组件。

假设我有一个包含TCombo TComboFrame的框架Combo1,我在主窗体的几个位置使用它。

当我将TComboFrame MyFrame1的实例放到我的主窗体上时,我想分配一个 组合的事件处理程序,我通过点击里面的TCombo来做到这一点 我放在表单上的框架MyFrame1,然后双击空框 对象检查器“事件”选项卡中的OnChange字段。

通常会创建一个名为的新处理程序:

procedure TMainForm.MyFrame1Combo1Change(Sender: TObject);

并且事件处理程序名称源自祖先TComboFrame(Combo1)上的组件名称以及我在表单上放置的实例的名称(MyFrame1) - 即唯一到TComboFrame的那个实例。我可以 为我放在主要框架上的其他框架实例执行此操作 形式,他们每个人都有自己的事件处理程序。

如果我想要为框架的所有实例触发事件处理程序, 我会打开祖先框架并在那里做。

这是我对它应该如何工作的理解,但有些东西 某处出了问题。在我的主要框架的几个实例中 表单,一些有自己的事件处理程序,有些具有公共事件处理程序,

procedure TDMainForm.ComboFrame1Combo1Change(Sender: TObject);

我没有尝试过打破Delphi似乎与之相关的幻影链接 这个公共事件处理程序由几个框架共享。

我怎样才能修复这种状态,以及首先导致它的原因?

**更新1 **

我在阅读了回复并进行了一些实验后发现我可以通过以下步骤修复有问题的组件:

1)删除框架的所有事件处理程序  2)删除框架,记住它的名称  3)复制另一个已知可行的(即它拥有自己的“个人”事件名称)  4)粘贴一个代替你删除的那个  5)恢复原始名称  6)创建事件处理程序。

......至少,它至少对我有用一次......

**更新2 **

另一种解决方法似乎是在双击Object Inspector中的空事件字段时,使用新的唯一名称来改写它创建的事件处理程序名称,然后再次双击该名称。然后Delphi创建一个具有唯一名称的空处理程序。

3 个答案:

答案 0 :(得分:3)

我会在框架中写另一个事件,并在我想要另一个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;

我通常这样做是因为我不相信delphi在DFM中设置事件的方式,很容易在不注意的情况下删除整个事件。

答案 1 :(得分:1)

只需单击要断开链接的TCombo,在对象检查器中清除其OnClick事件处理程序分配,然后双击该事件即可生成新的事件处理程序当然,如果生成的事件处理程序名称已经存在,它将被重用,但至少Object Inspector将在生成事件时重新评估所有对象名称。

当然,这不是一种非常面向对象的方法。 Fabio建议的是更好的选择。虽然我建议将TFrame事件声明为published而不是public,因此您可以在设计时将其分配给任何其他事件。

答案 2 :(得分:1)

我无法在Delphi6或Delphi 2009中重新创建这种行为。在我看来有很多帧(并且可能更改它们的名称添加和删除)你愚弄/迷惑了Delphi的命名约定,它默认使用它来链接事件和框架最终与之前的名称相同。

因此,双击事件处理程序只会将事件处理程序与由先前删除(或重命名)的框架创建的事件处理程序同名(但删除框架不会删除旧的事件处理程序.IYSWIM :)

因此,我的回答是你已经通过获取帧名称和混乱中的事件处理程序名称!