2015-07-22 82 views
5

我有3個類,即登錄,條碼和主。
登錄類只包含用戶的身份驗證。
條碼類具有以下代碼片段:如何避免重複訂閱活動?

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); 
     } 

    } 

而在主類,條形碼事件的subsciption完成:

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 
     } 

    } 

事件訂閱的重複,當我嘗試註銷併發生再次登錄。
當我嘗試調試時,BarcodeReadOut被調用兩次。
在註銷時,在打開登錄屏幕之前調用removeInstance(),並且Main窗體爲Close()和Dispose()。
有人可以幫助我如何避免上述事件的重複?

我也註冊了事件之前這樣做,但什麼也沒有發生:

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

可以清除所有帶反射的eventsubscriptions。看看這裏http://stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control –

+1

你可以檢查'barcode.BarcodeReadOut == null' – Hassan

+1

上面的鏈接是好的,但一定要閱讀,因爲接受的答案似乎不是最好的。 – TaW

回答

0

你應該添加和刪除處理程序如下:

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 
    } 

} 

另外:你並不需要定義自定義委託,您可以使用通用的EventHandler

public event EventHandler<BarcodeEventArgs> BarcodeReadOut; 
0

這將是很好將所有適用於條碼的邏輯移至單獨的類。它可能是很好的補充通知(在你的情況下,Form類)其他類已發生的事件自定義事件:

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); 
    } 
} 

,並使用它像這樣:

BarcodeWorker barcode = new BarcodeWorker(); 

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