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:
4

3 回答 3

4

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

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

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

于 2013-01-22T23:08:13.410 回答
1

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

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

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

MyObject.ItemInsertedEvent += myHandler;

编辑: Jon Skeet 关于比赛条件问题是正确的,你应该像他建议的那样使用局部变量。我已经改变了我的例子来匹配。

于 2013-01-22T23:08:30.350 回答
0

这是因为事件发生null在你调用它的时候。您需要检查它是否null事先:

if (ItemInsertedEvent != null) {
    ItemInsertedEvent(this, args);
}
于 2013-01-22T23:09:22.793 回答