2012-04-06 13 views
2

Ich habe Schwierigkeiten, Delphi 2006 zu bekommen, um Event-Handler einer Komponente auf einem TFrame zuzuweisen, die unabhängig sind.Wie kann ich eine Komponente in einem TFrame zwingen, einen eigenen Event-Handler zu haben?

Angenommen, ich habe einen Rahmen TComboFrame, der ein TCombo Combo1 enthält, und ich verwende dieses an mehreren Stellen auf meinem Hauptformular.

Wenn ich eine Instanz von TComboFrame MyFrame1 auf meine Hauptform platzieren, und ich möchte ein Ereignishandler der Combo zuweisen, das tue ich es von innen den Rahmen auf dem TCombo klicken MyFrame1, die ich auf dem Formular platziert haben und doppelklicken Sie in das leere Feld OnChange im Objektinspektor Ereignisse Registerkarte.

Normalerweise erzeugt den einen neuen Handler mit einem Namen wie:

procedure TMainForm.MyFrame1Combo1Change(Sender: TObject); 

und die Ereignisbehandlungsroutine Name wird von sowohl den Namen der Komponente, auf dem Vorfahren TComboFrame (Combo1) und den Namen der Instanz abgeleitet I habe auf meinem Formular (MyFrame1) platziert - dh einzigartig für diese Instanz des TComboFrame. Ich kann dann dies für andere Instanzen des Rahmens tun, die ich auf meinem Hauptformular platziert habe und sie erhalten jeweils ihre eigenen Event-Handler.

Wenn ich einen Event-Handler wollte, der für alle Instanzen des Rahmens ausgelöst wurde, würde ich den Vorgängerrahmen selbst öffnen und es dort tun.

Das ist mein Verständnis davon, wie es funktionieren soll, aber etwas hat irgendwo schief gelaufen. Von den verschiedenen Instanzen des Rahmens auf meiner Haupt- Form, einige haben ihre eigenen Event-Handler, und einige haben einen gemeinsamen Event-Handler,

procedure TDMainForm.ComboFrame1Combo1Change(Sender: TObject); 

Nichts, was ich versucht habe, hat dieses Phantom Link Delphi mit zu haben scheint gebrochen Dieser allgemeine Event-Handler wird von mehreren Frames gemeinsam genutzt.

Wie kann ich diesen Zustand reparieren, und was verursacht ihn überhaupt?

** UPDATE ** 1

Ich habe festgestellt, nachdem die Antworten zu lesen und ein wenig experimentieren, dass ich die problematischen Komponenten durch das folgende Verfahren reparieren:

1) entfernen Sie alle Event-Handler für die Rahmen.
2) löschen Sie den Rahmen und erinnern Sie sich an seinen Namen.
3) Kopieren Sie eine andere, von der bekannt ist, dass sie in Ordnung ist (d. H. Sie hat eigene Ereignisnamen, die "individuell" sind).
4) fügen Sie dieses anstelle des gelöschten ein.
5) Wiederherstellen des ursprünglichen Namens.
6) Erstellen Sie Ihre Ereignishandler.

... zumindest funktionierte es für mich mindestens einmal ...

** UPDATE ** 2

Ein anderer Weg zur Heilung es den Event-Handler Namen zu sein scheint zu überschreiben, die es erstellt, wenn Sie einen Doppelklick auf dem leeren Ereignisfeld im Objektinspektoren mit einem neuen eindeutigen Namen , und doppelklicken Sie dann erneut auf den Namen. Delphi erstellt dann einen leeren Handler mit dem eindeutigen Namen.

Antwort

3

Ich würde ein anderes Ereignis in dem Rahmen schreiben und sie setzen, wenn ich ein anderes Ereignis OnChange möchten, wie folgt aus:

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; 

Und wo muss ich etwas zu dem OnChange Verhalten hinzuzufügen:

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; 

Normalerweise mache ich das, weil ich der Delphi-Methode, Ereignisse im DFM zu setzen, nicht traue, es ist sehr einfach, einfach das ganze Ereignis zu entfernen, ohne es zu merken.

1

Klicken Sie einfach auf einen TCombo, auf den Sie die Verknüpfung aufheben möchten, löschen Sie die Event-Handler-Zuordnung im Objektinspektor, und doppelklicken Sie dann auf das Ereignis, um einen neuen Event-Handler zu generieren. Wenn der Name des generierten Event-Handlers bereits existiert, wird er natürlich wiederverwendet, aber der Objektinspektor wertet alle Objektnamen beim Generieren des Events mindestens erneut aus.

Natürlich ist dies kein sehr objektorientierter Ansatz. Was Fabio vorschlägt, ist eine bessere Wahl. Obwohl ich vorschlagen würde, das TFrame Ereignis als published anstelle von public zu deklarieren, so können Sie es zur Entwurfszeit wie jedes andere Ereignis zuweisen.

+0

Ich mag auch keine veröffentlichten Ereignisse, wenn Sie sie jemals entfernen müssen, werden Sie nur in der Laufzeit Fehler erhalten. Wenn es mir möglich ist, möchte ich es vermeiden, veröffentlichte Ereignisse zu deklarieren. Es ist nur gut, wenn es eine Endbenutzerkomponente ist, die Sie freigeben möchten und möchten, dass sie die Ereignisse im Objektinspektor festlegen. –

+0

Danke @Remy. Immer noch keine Würfel. Ich bekomme immer noch einen Handler mit einem Namen, der auf dem Namen des Vorfahren und nicht auf der individuellen Komponente basiert, und das passiert dann für alle anderen Events dieses Frames und alle anderen Instanzen des Frames, die "beschädigt" sind. Der Event-Handler-Name existiert nicht bereits in meiner Quelle. Siehe Anhang zum OP für mehr. – rossmcm

1

Ich kann dieses Verhalten nicht in Delphi6 oder Delphi 2009 neu erstellen. Es scheint mir mit vielen Frames (und Ändern ihrer Namen Hinzufügen und Löschen vielleicht) Sie haben Delphi Benennungskonvention getäuscht/verwirrt, die es standardmäßig verwendet, um zu verknüpfen Die Events und Frames haben dieselben Namen wie die vorherigen.

Durch Doppelklick auf die Ereignisbehandlungsroutinen gelangen Sie einfach zu einer Ereignisbehandlungsroutine mit demselben Namen wie eine zuvor gelöschte (oder umbenannte) Rahmenstruktur (das Löschen der Rahmen löscht jedoch nicht die alten Ereignisbehandlungsroutinen. IYSWIM:)

Daher meine Antwort ist Sie haben durch die Frames Namen & Event-Handler-Namen in einem Wirrwarr verwirrt bekommen!

Verwandte Themen