2015-07-22 16 views
5

Ich habe 3 Klassen nämlich Login, Barcode und Main.
Login-Klasse enthält nur die Authentifizierung der Benutzer.
Barcode Klasse hat folgende Snippet-Code:Wie vermeidet man doppelte Abonnements?

class Barcode 
    { 
     public delegate void BarcodeReadHandler(object sender, BarcodeEventArgs e); 
     public event BarcodeReadHandler BarcodeReadOut; 

     public Barcode() 
     { 
     //.. some codes for getting data on the scanner 
     BarcodeEventArgs args = new BarcodeEventArgs(scannedData); 
     BarcodeReadOut(this, args); 
     } 

    } 

Während in Hauptklasse, die subsciption des Barcode-Ereignis geschehen ist:

public partial class Main : Form 
    { 
     private Barcode barcode = null; 

     public Main() 
     { 
     barcode.BarcodeReadOut += new barcode.BarcodeReadHandler(getBarcodeStr); 
     } 

     //This is called before log-out. 
     public void removeInstance() 
     { 
     barcode.BarcodeReadOut -= new barcode.BarcodeReadHandler(getBarcodeStr); 
     } 

     private void getBarcodeStr(object sender, BarcodeEventArgs e) 
     { 
     //some code 
     } 

    } 

Die Vervielfältigung von Ereignisabonnement passiert, wenn ich abzumelden versuchen und nochmal anmelden.
Wenn ich versuchte zu debuggen, wird BarcodeReadOut zweimal aufgerufen.
Beim Abmelden wird die Methode removeInstance() aufgerufen und das Hauptformular ist Close() und Dispose(), bevor der Anmeldebildschirm geöffnet wird.
Kann mir jemand helfen, wie ich die Wiederholung der besagten Ereignisse vermeiden kann?

Ich habe auch dies getan, bevor das Ereignis registriert, aber nichts passiert:

public Main() 
    { 
     barcode.BarcodeReadOut -= new barcode.BarcodeReadHandler(getBarcodeStr); 
     barcode.BarcodeReadOut += new barcode.BarcodeReadHandler(getBarcodeStr); 
    } 
+2

Sie können alle löschen Veranstaltungen mit Reflexionen. Schauen Sie hier http://stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control –

+1

können Sie überprüfen nach 'barcode.BarcodeReadOut == null' – Hassan

+1

Der Link oben ist gut, aber lesen Sie es durch, denn die angenommene Antwort scheint nicht die beste zu sein. – TaW

Antwort

0

Sie sollten den Handler hinzufügen und entfernen Sie wie folgt vor:

public partial class Main : Form 
{ 
    private Barcode barcode = null; 

    public Main() 
    { 
    barcode.BarcodeReadOut += getBarcodeStr; 
    } 

    //This is called before log-out. 
    public void removeInstance() 
    { 
    barcode.BarcodeReadOut -= getBarcodeStr; 
    } 

    private void getBarcodeStr(object sender, BarcodeEventArgs e) 
    { 
    //some code 
    } 

} 

auch: Sie brauchen nicht zu definieren eine benutzerdefinierte delegieren, können Sie die generische EventHandler verwenden:

public event EventHandler<BarcodeEventArgs> BarcodeReadOut; 
0

Es wäre gut um all Ihre Logik, die mit Barcode arbeitet, in eine separate Klasse zu verschieben. Und es könnte gut sein, ein benutzerdefiniertes Ereignis hinzufügen, die anderen Klassen (eine Form-Klasse in Ihrem Fall) teilt mit, dass Ereignis aufgetreten ist:

class Barcode 
{ 
    public delegate void BarcodeReadHandler(object sender, BarcodeEventArgs e); 
    public event BarcodeReadHandler BarcodeReadOut; 

    public Barcode() 
    { 
    //.. some codes for getting data on the scanner 
    BarcodeEventArgs args = new BarcodeEventArgs(scannedData); 
    BarcodeReadOut(this, args); 
    } 

} 

class BarcodeWorker 
{ 
    private Barcode barcode = null; 
    private BarcodeReadHandler handler; 
    public event BarcodeEventArgs scanComplete; 

    BarcodeWorker(Barcode barcode) 
    { 
     if(barcode == null) this.barcode = barcode; 
    } 

    public AddEventHandler() 
    { 
     if(handler != null) return; 
     handler = new BarcodeReadHandler(getBarcodeStr); 
     barcode.BarcodeReadOut += handler; 
    } 

    //This is called before log-out. 
    public void RemoveEventHandler() 
    { 
     barcode.BarcodeReadOut -= handler; 
     handler = null; 
    } 

    private void getBarcodeStr(object sender, BarcodeEventArgs e) 
    { 
     scanComplete(sender, e); 
    } 
} 

und es wie folgt verwendet werden:

BarcodeWorker barcode = new BarcodeWorker(); 

barcode.scanComplete += // your delegate with event handler or with anonymous method here; 
Verwandte Themen