尝试使用自定义事件时出错

时间:2013-01-22 23:05:51

标签: c# winforms custom-events

我正在尝试使用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:

3 个答案:

答案 0 :(得分:4)

您可能没有任何订阅此活动。如果是这种情况,那么支持您的事件的委托字段将具有空值。您应该检查一下,如下所示:

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

使用局部变量的原因是为了避免竞争条件,在检查之后但在调用之前删除最后一个处理程序

答案 1 :(得分:1)

您没有附加任何事件处理程序。通常,自定义事件代码会检查:

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

您需要在某处添加一些处理程序,即

MyObject.ItemInsertedEvent += myHandler;
编辑:Jon Skeet对竞争条件问题是对的,你应该像他建议的那样使用局部变量。我改变了我的例子来匹配。

答案 2 :(得分:0)

这是因为当您调用它时,事件为null。您需要事先检查它是否为null

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