Hinzufügen eines eigenen Event-Handlers vor anderen Event-Handlern

8

Wenn ich AddHandler in VB verwende, um dem Click-Ereignis eine eigene Methode hinzuzufügen:

%Vor%

Ich sehe, dass mein Code zuletzt ausgeführt wird - nach anderen Ereignishandlern für das Button_Click-Ereignis. Gibt es eine Möglichkeit, meinen Ereignishandler vor anderer Ereignisse einzufügen, damit er zuerst ausgeführt wird?

Ich habe diese Frage sowohl als C # als auch als VB markiert, bitte zögern Sie nicht, entweder Sprache zu verwenden, wenn Sie irgendwelche Vorschläge haben.
Danke!

    
Meringros 24.09.2010, 17:13
quelle

4 Antworten

5

Die Reihenfolge der Ausführung von Handlern eines einzelnen Ereignisses kann nicht durch das grundlegende Verhalten eines integrierten Ereignisses selbst gesteuert werden. MulticastDelegates sind "Taschen" von Handlern, und sie greifen sie nur einzeln an. Denken Sie daran, dass dies von den meisten Entwicklern erwartet wird und dass es gefährlich sein kann, auftragsabhängige Ereignisbehandlungsroutinen zuzulassen. Event-Handler sollten normalerweise nicht voneinander wissen, denn wenn sie davon abhängig sind, vor oder nach einem anderen Handler ausgeführt zu werden, müssen sie zuerst von der Existenz des anderen Handlers wissen (Verletzung des Verbergens von Informationen und anderer Design-Prinzipien). Wenn sich diese Reihenfolge ändert, wird das Verhalten unterbrochen.

Wenn Sie all dies verstehen und trotzdem die Ausführungsreihenfolge von Handlern eines Ereignisses steuern möchten, werden Sie durch folgende Schritte nah dran sein.

  1. Erstellen Sie eine geordnete Sammlung von Delegaten des Ereignishandlertyps namens MyHandlers. Dies wird ein Surrogat für die MulticastDelegate-Implementierung des tatsächlichen Ereignisses sein.
  2. Erstellen Sie eine "Master" -Handlermethode, die tatsächlich an das integrierte Ereignis angefügt wird, und durchläuft MyHandlers und ruft jedes einzelne auf.
  3. Definieren Sie einige Mittel zum Hinzufügen und Entfernen von Handlern aus der Liste. Einiges davon kann mit einer benutzerdefinierten Ereignis- "Eigenschaft" erreicht werden, aber das definiert nur Verhalten hinzufügen und entfernen, nicht einfügen.

Der Code könnte wie folgt aussehen:

%Vor%

Beachten Sie, dass Sie keine anderen Handler als MasterClickHandler an das tatsächliche Ereignis anhängen. Sie können Ihren Kuchen nicht essen und auch nicht essen, indem Sie das grundlegende Ereignisverhalten außer Kraft setzen und behalten. In das Ereignis "property" ist auch kein "insert" -Verhalten eingebaut; Sie müssen eine Methode definieren, die dies erlaubt. Schließlich sollten Sie das Ereignis MyControlButtonClick niemals direkt auslösen (obwohl Ihr Steuerelement das einzige ist, das dies kann, kann dies durch eine Codeüberprüfung erzwungen werden).

Wenn Sie nun auf die Schaltfläche klicken, löst das integrierte Click-Ereignis der Schaltfläche MasterEventHandler aus, wodurch die Delegaten in MyHandlers in der Reihenfolge ausgeführt werden, in der sie an MyControlButtonClick (in umgekehrter Reihenfolge zuerst eingefügt) angefügt wurden sie wurden eingefügt). Wenn Sie diesen Code mit dem Button in ein benutzerdefiniertes Benutzersteuerelement eingefügt haben, könnten Sie sogar das benutzerdefinierte Ereignis auf Ihrem Steuerelement als Click bezeichnen. Das Steuerelement würde genauso aussehen und funktionieren wie der enthaltene Button, außer dass es zusätzliche Kontrolle über das Einfügen hätte Handler. Die Schönheit der ganzen Sache ist, dass nichts über diesen Code die Verbraucher zwingt, mit ihr als etwas anderes als ein einfaches ol vanille Ereignis zu arbeiten.

    
KeithS 24.09.2010, 17:58
quelle
11

Nicht leicht.

Sagen Sie es nicht, tun Sie es nicht. Ihr Code sollte sich nicht darum kümmern, in welcher Reihenfolge er aufgerufen wird - es sollte nur darauf achten, dass auf den betreffenden Button geklickt wurde. Alle Handler, einschließlich Ihrer, werden ausgeführt. Wenn die Reihenfolge wichtig ist, sollten Sie Ihr Design überdenken und einen anderen Mechanismus verwenden, um dies zu kontrollieren.

    
Reed Copsey 24.09.2010 17:17
quelle
4

Es ist mehr ein Implementierungsdetail von VB.NET, es bietet eine alternative Möglichkeit, mit Ereignissen umzugehen, die die Schlüsselwörter WithEvents und Handles verwenden. Ein Ereignishandler, der Handles verwendet, wird von automatisch generiertem Code im Formularkonstruktor abonniert. Dieser Code wird vor jedem Code ausgeführt, einschließlich InitializeComponent oder Ihrer benutzerdefinierten AddHandler-Anweisung. Und wird also immer zuerst laufen.

Es ist möglich, dass Sie Ihren Code erhalten, damit er als erster ausgeführt werden kann. Leiten Sie Ihre eigene Klasse von Button ab und überschreiben Sie die OnClick-Methode:

%Vor%     
Hans Passant 24.09.2010 17:37
quelle
2

Ich hatte ein ähnliches Problem.

Ich hatte ein Ereignis: Geschlossen, dass zwei verschiedene Objekte zuhören. Und ich musste sicher sein, dass das Ereignis des ersten Objekts vor dem zweiten aufgerufen wird.

Hier seine meine Lösung (in C #):

%Vor%

So für alle Ereignisse möchte ich zuerst genannt werden:

%Vor%

Und für alle Ereignisse möchte ich zuletzt genannt werden:

%Vor%

* Das Hinzufügen eines Ereignisses in beide Richtungen ist dasselbe, mit und ohne "new EventHandler ()"

Ich hoffe, ich war hilfreich.

    
Gil Epshtain 27.12.2013 15:03
quelle

Tags und Links