2013-01-22 44 views
0

我試圖使用Passing-Data-between-Windows-Forms白皮書中的信息編寫一些自定義事件以在表單之間傳遞信息。
不幸的是,當我嘗試提高事件時,我總是收到NullReferenceException。以下是我目前嘗試使用的相關代碼的縮小版本。
有人可以請看看,讓我知道如果我失去了一些東西?
順便說一句,我使用DevExpress表格,如果這有所作爲。我只包含正在生成自定義事件的類,因爲那是代碼失敗的地方。在發生NullReferenceException的行上,我已驗證該項目不是null嘗試使用自定義事件時出錯

// Class that generates custom event 
public partial class DiscountItemControl : DevExpress.XtraEditors.XtraUserControl 
{ 
    // Add a delegate 
    public delegate void ItemInsertedEventHandler(object sender, ItemInsertedEventArgs e); 

    // AddCustomerForm an event of the delegate type 
    public event ItemInsertedEventHandler ItemInsertedEvent; 

    public void SaveAndClose() 
    { 
     // setup event args 
     ItemInsertedEventArgs args = new ItemInsertedEventArgs(currentDiscountItem); 

     // ********** THIS THROWS NullReferenceException ********* 
     // raise the event to notify listeners 
     ItemInsertedEvent(this, args); 

     this.Dispose(); 
    } 
} 

// Event arguments for event 
public class ItemInsertedEventArgs : System.EventArgs 
{ 
    private Item item; 

    public ItemInsertedEventArgs(Item item) 
    { 
     this.item = item; 
    } 

    public Item InsertedItem 
    { 
     get 
     { 
      return this.item; 
     } 
    } 
} 

System.NullReferenceException was unhandled by user code Message="Object reference not set to an instance of an object." Source="PureService" StackTrace: 
at MarineService.Tests.DiscountItemControl.SaveAndClose(Boolean& result) in C:\Aaron\Dev\HIGH PRIORITY\ServiceModule\MarineService\ServiceModule\UtilityClasses\UserControls\Items\DiscountItemControl.cs:line 336 
at MarineService.Tests.AddEditItemForm.btnSaveAndClose_Click(Object sender, EventArgs e) in C:\Aaron\Dev\HIGH PRIORITY\ServiceModule\MarineService\ServiceModule\AddEditItemForm.cs:line 326 
at System.Windows.Forms.Control.OnClick(EventArgs e) 
at DevExpress.XtraEditors.BaseButton.OnClick(EventArgs e) 
at DevExpress.XtraEditors.BaseButton.OnMouseUp(MouseEventArgs e) 
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 
at System.Windows.Forms.Control.WndProc(Message& m) 
at DevExpress.Utils.Controls.ControlBase.WndProc(Message& m) 
at DevExpress.XtraEditors.BaseControl.WndProc(Message& msg) 
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) InnerException: 

回答

1

您沒有附加任何事件處理程序。通常自定義事件代碼有一個檢查:

ItemInsertedEventHandler handler = this.ItemInsertedEvent; 
if(handler != null) handler(this, args); 

你需要有一些代碼的地方,增加了一個處理程序,即

MyObject.ItemInsertedEvent += myHandler; 

編輯:喬恩斯基特是正確的關於競爭條件的問題,您應該像他所建議的那樣使用局部變量。我改變了我的例子以匹配。

+0

謝謝,今天是第一次,我在每天嘗試寫我自己的自定義事件。我試圖從其他表單可以訂閱的一種表單中發起事件。上面白皮書中最初遺漏的細節是,他們使用工廠來創建處理程序所連接的所有表單的實例。工廠是完成在我的表單之間發送數據的最佳途徑嗎?我不想通過在構造函數中傳遞引用來緊密耦合表單。 – Grasshopper

+0

沒有看到你的整個應用程序很難說什麼是最好的路線,但它聽起來像你是正確的避免在構造函數中傳遞形式引用。 – WildCrustacean

4

機會是你沒有對事件的任何用戶。如果是這種情況,則支持事件的委託字段將具有空值。您應該檢查對於這一點,就像這樣:

ItemInsertedEventHandler handler = ItemInsertedEvent; 
if (handler != null) 
{ 
    handler(this, args); 
} 

之所以使用一個局部變量是避免競爭條件,其中最後一個處理程序檢查之後,但在調用之前刪除。

0

這是因爲您調用它時事件爲null。你需要檢查它是否是事先null

if (ItemInsertedEvent != null) { 
    ItemInsertedEvent(this, args); 
} 
相關問題